O que é Java Semaphore e Mutex – Java Concurrency MultiThread explicado com exemplo

Publicados: 2015-03-12

Tutorial Java Mutex e Semáforo por Crunchify

Java Concurrency é um tópico muito amplo. Existem centenas de tutoriais e exemplos disponíveis para uso. Algum tempo atrás eu escrevi alguns tutoriais sobre Run Multiple Threads Simultaneamente em Java e diferentes tipos de Blocos Sincronizados.

Neste tutorial iremos abordar:

  1. Explicação do Mutex
  2. Explicação do Semáforo
  3. Dois exemplos com detalhes

Vamos começar

Let's keep this in mind ao ler a explicação abaixo:

  • Tome um exemplo de Comprador e Cliente
  • O cliente está emprestando laptops
  • O cliente pode vir e usar o Laptop - o cliente precisa de uma chave para usar um Laptop
  • Após o uso - o cliente pode devolver o Laptop ao Shopper

O que é Mutex (Apenas 1 thread):

O cliente tem uma chave para um laptop. Um cliente pode ter a chave – emprestar um Laptop – no momento. Quando a tarefa termina, o Shopper entrega (libera) a chave para o próximo cliente da fila.

Official Definition :

“Mutex é normalmente usado para serializar o acesso a uma seção de re-entrant code que cannot be executed concurrently por mais de um thread. Um objeto mutex permite apenas um thread em uma seção controlada, forçando outros threads que tentam obter acesso a essa seção a esperar até que o primeiro thread saia dessa seção. ”

Em outras palavras: Mutex = Mutually Exclusive Semaphore

O que é Semáforo (N threads especificados):

Digamos que agora o Shopper tenha 3 laptops idênticos e 3 chaves idênticas. Semáforo é o número de free identical Laptop keys . A contagem de semáforos – a contagem de chaves – é definida como 3 no início (todos os três laptops estão livres), então o valor da contagem é decrementado à medida que o cliente está chegando. Laptop, a contagem de semáforos é 0. Agora, quando algum cliente devolve o Laptop, o semáforo é aumentado para 1 (uma chave livre), e dado ao próximo cliente na fila.

Official Definition : “Um semáforo restringe o número de usuários simultâneos de um recurso compartilhado até um número máximo. Threads podem solicitar acesso ao recurso (diminuindo o semáforo) e podem sinalizar que terminaram de usar o recurso (incrementando o semáforo).”

Outro deve ler: Lazy Creation of Singleton ThreadSafe Instance

Exemplo-1: (Explicação abaixo)

No tutorial acima CrunchifySemaphoreMutexTutorial.java quando o CrunchifyProducer adiciona threadName ao objeto crunchifyList linkedList ele pode sinalizar o semáforo.

O CrunchifyConsumer pode então estar tentando adquirir o semáforo para que aguarde até que o CrunchifyProducer sinalize que um threadID foi adicionado. Ao sinalizar um dado adicionado, um dos consumidores será acordado e saberá que pode ler um objeto crunchifyList. Ele pode ler uma lista e depois voltar a tentar adquirir no semáforo.

Se nesse tempo o produtor escreveu outro pacote, ele sinalizou novamente e qualquer um dos consumidores irá ler outro pacote e assim por diante…

Em outras palavras:

Resultado:

Como evitar a condição de corrida:

What if you have multiple Consumers? No Tutorial Java acima Os consumidores (não o produtor) devem bloquear o buffer ao ler o pacote (mas não ao adquirir o semáforo) para evitar condições de corrida. No exemplo abaixo, o produtor também bloqueia a lista, pois tudo está na mesma JVM.

Exemplo-2:

Resultado: