Em Java, usamos semáforo na sincronização de threads. Ele é usado para controlar o acesso a um recurso compartilhado que usa uma variável contador. Java também fornece uma classe Semaphore que contém construtores e vários métodos para controlar o acesso sobre o recurso compartilhado. Vamos discuti-lo mais tarde nesta seção.

Antes de avançar nesta seção, primeiro, vamos entender o que é semáforo, tipos de semáforo, como ele funciona e como implementar semáforo. Depois de saber tudo sobre isso, vamos passar para os programas de semáforo Java.

O que é um semáforo?

Um semáforo é usado para limitar o número de threads que querem acessar um recurso compartilhado. Em outras palavras, é uma variável não-negativa que é compartilhada entre os threads conhecidos como um contador. Ela define o limite dos threads. Um mecanismo no qual um thread está esperando em um semáforo pode ser sinalizado por outros threads.

  • Se contador > 0, o acesso aos recursos compartilhados é fornecido.
  • Se contador = 0, o acesso aos recursos compartilhados é negado.

Em suma, o contador continua rastreando o número de permissões que ele deu a um recurso compartilhado. Portanto, semáforo concede permissão a threads para compartilhar um recurso.

Características de Semáforo

Existem as seguintes características de um semáforo:

  • Provê sincronização entre os threads.
  • Diminui o nível de sincronização. Portanto, fornece um mecanismo de sincronização de baixo nível.
  • O semáforo não contém um valor negativo. Ele contém um valor que pode ser maior que zero ou igual a zero.
  • Podemos implementar o semáforo usando a operação de teste e interrupções, e usamos os descritores de arquivo para executá-lo.

Trabalho de Semáforo

Controles de semáforo sobre o recurso compartilhado através de uma variável contador. O contador é um valor não-negativo. Ele contém um valor maior que 0 ou igual a 0,

  • Se o contador > 0, o thread obtém permissão para acessar o recurso compartilhado e o valor do contador é decrescido em 1,
  • Else, o thread será bloqueado até que uma permissão possa ser adquirida.
  • Quando a execução do thread é completada, então não há necessidade do recurso e o thread o libera. Após liberar o recurso, o valor do contador incrementado em 1.
  • Se outro thread estiver esperando para adquirir um recurso, o thread irá adquirir uma permissão nesse momento.
  • Se o contador = 0, o thread não terá permissão para acessar o recurso compartilhado.

Vamos entender o funcionamento do semáforo com a ajuda de um fluxograma.

Semáforo JavaTipos de Semáforos

Existem quatro tipos de semáforos, que são os seguintes:

  • Contagem de Semáforos
  • Semáforos encadernados
  • Semáforos com tempo
  • Semáforos binários

Semáforo Java

Vamos discutir um a um em detalhe.

Contagem de Semáforos

Os semáforos de contagem são usados para resolver a situação em que mais de um processo quer executar na secção crítica, simultaneamente. Portanto, para superar este problema, usamos semáforos de contagem. Por exemplo, considere o seguinte trecho de código.

Vejamos a implementação dos semáforos de contagem.

Semáforos de contagemExemplo.java

Semáforos encadernados

Podemos definir o limite superior usando os semáforos encadernados. Ele é usado no lugar dos semáforos de contagem porque os semáforos de contagem não contêm nenhum valor limite superior. O valor limite superior denota quantos sinais ele pode armazenar. Por exemplo, considere o seguinte código snippet.

Vejamos a implementação do semáforo limitado.

Semáforo limitadoExample.java

Semáforo limitado

Os semáforos temporizados permitem que um thread funcione por um período de tempo especificado. Após um determinado tempo, o temporizador reinicia e libera todas as outras permissões.

Vejamos a implementação dos semáforos temporizados.

TimedSemaphoresExample.java

Semáforos binários

Os semáforos binários são os mesmos que contam os semáforos. Mas lembre-se que ele aceita apenas valores binários 0 ou 1. A sua implementação é fácil em comparação com outros semáforos. Se o valor for 1, a operação do sinal é bem sucedida, falha de outra forma.

Vejamos a implementação dos semáforos binários.

Semáforos bináriosExample.java

Semáforo em Java

Em Java, é uma construção de sincronização de threads. O construtor usa uma variável conhecida como contador que controla o acesso sobre o recurso compartilhado. É um tipo de variável que é usada para gerenciar processos simultâneos e também sincronizá-los. Ela também é usada para evitar condições de corrida. Ela restringe o número de threads para acessar um recurso compartilhado.

Por exemplo, podemos restringir um arquivo para acessar até 10 conexões simultaneamente.

Java Semaphore Class

Java fornece uma classe Semaphore para implementar o mecanismo de semáforo. Ela pertence ao pacote java.util.concurrent. Ele implementa a interface Serializável. Portanto, a implementação manual não é necessária.

A classe Semaphore provê os seguintes dois construtores:

  • Semaphore(int permits)
  • Semaphore(int permits, boolean fair)

Semaphore(int permits)

Cria um Semaphore e analisa o número de permissões (número inicial de permissões disponíveis) como um argumento. Ele especifica o número de threads que podem compartilhar um recurso de cada vez. O valor das permissões pode ser negativo. Neste caso, uma liberação deve ocorrer antes que qualquer aquisição seja concedida.

Syntax:

Semaphore(int permits, boolean fair)

Cria um Semaphore com o número dado de permissões e as configurações de justiça.

Syntax:

Parses dois parâmetros:

  • permissões: O valor das permissões pode ser negativo. Neste caso, a liberação deve ocorrer antes que qualquer aquisição seja concedida.
  • justo: Se definirmos o valor como verdadeiro, o semáforo garante FIFO aos threads na ordem em que são solicitados, falso Por padrão, todos os threads que estão esperando pela permissão de concessão de recursos em uma ordem indefinida.

Métodos da Classe Semáforo

A classe fornece os seguintes métodos:

aquirir() Método: O método adquire as licenças do semáforo, bloqueando até que uma esteja disponível, ou o fio seja interrompido. Ele reduz o número de licenças disponíveis em 1.

Se não houver nenhuma licença disponível para a thread atual, a thread fica desabilitada para fins de programação de threads. A thread atual vai para o estado inativo até que uma de duas coisas aconteça:

  • Se a outra thread invocar o método release() para liberar o recurso, então a thread atual recebe permissões.
  • Se a outra thread interromper a thread atual.

Lança InterruptedException se a thread atual for interrompida. O método não retorna nenhum valor.

Syntax:

release() Método: Ele libera uma permissão e a retorna para o semáforo. Ele aumenta o número de permissões disponíveis por 1. Se um thread tentar adquirir uma permissão, o semáforo concede permissão para adquirir o recurso que acabou de ser liberado por outros threads. Além disso, essa thread é considerada para fins de programação de threads.

Syntax:

availablePermits() Method: O método retorna o número de licenças disponíveis em semáforo para a concessão do recurso. Normalmente, ele é usado para fins de depuração e teste.

Sintaxe:

Deixe entender os métodos acima através de um exemplo simples.

Usando Semáforo como Bloqueio

Java nos permite usar um semáforo como um bloqueio. Isso significa que bloqueia o acesso ao recurso. Qualquer thread que queira acessar o recurso bloqueado, deve chamar o método acquire() antes de acessar o recurso para adquirir o bloqueio. O thread deve liberar o bloqueio chamando o método release(), após a conclusão da tarefa. Lembre-se de que definir o limite superior como 1. Por exemplo, considere o seguinte trecho de código:

Vejamos um exemplo de semáforo e use semáforo como um lock.

SemaphoreAsLock.java

Output:

Java Semaphore

Note: Quando executamos o programa acima, obtemos uma saída diferente a cada vez. Assim, a sua saída pode ser diferente da saída mostrada acima.

Java Semaphore Example

Vamos entender o mecanismo do semáforo através de um programa Java. No exemplo a seguir, criamos um construtor da classe Semaphore com o valor inicial de permissão 3.

SemaphoreExample.java

Output:

Java Semaphore

Deixe uma resposta

O seu endereço de email não será publicado.