In Java, usiamo semaphore nella sincronizzazione dei thread. È usato per controllare l’accesso a una risorsa condivisa che usa una variabile contatore. Java fornisce anche una classe Semaphore che contiene costruttori e vari metodi per controllare l’accesso alla risorsa condivisa. Ne parleremo più avanti in questa sezione.

Prima di andare avanti in questa sezione, per prima cosa, capiremo cos’è il semaforo, i tipi di semaforo, come funziona, e come implementare il semaforo. Dopo aver saputo tutto, passeremo ai programmi Java semaforo.

Che cos’è un semaforo?

Un semaforo è usato per limitare il numero di thread che vogliono accedere a una risorsa condivisa. In altre parole, è una variabile non negativa che è condivisa tra i thread conosciuta come un contatore. Stabilisce il limite dei thread. Un meccanismo in cui un thread è in attesa di un semaforo può essere segnalato da altri thread.

  • Se il contatore > 0, l’accesso alle risorse condivise è fornito.
  • Se il contatore = 0, l’accesso alle risorse condivise è negato.

In breve, il contatore tiene traccia del numero di autorizzazioni che ha dato a una risorsa condivisa. Pertanto, il semaforo concede il permesso ai thread di condividere una risorsa.

Caratteristiche del semaforo

Ci sono le seguenti caratteristiche di un semaforo:

  • Fornisce la sincronizzazione tra i thread.
  • Minuisce il livello di sincronizzazione. Quindi, fornisce un meccanismo di sincronizzazione di basso livello.
  • Il semaforo non contiene un valore negativo. Tiene un valore che può essere maggiore di zero o uguale a zero.
  • Possiamo implementare il semaforo usando l’operazione di test e gli interrupt, e usiamo i descrittori di file per eseguirlo.

Funzionamento del semaforo

Il semaforo controlla la risorsa condivisa attraverso una variabile contatore. Il contatore è un valore non negativo. Contiene un valore maggiore di 0 o uguale a 0.

  • Se il contatore > 0, il thread ottiene il permesso di accedere alla risorsa condivisa e il valore del contatore viene decrementato di 1.
  • Altrimenti, il thread viene bloccato fino a quando non può essere acquisito un permesso.
  • Quando l’esecuzione del thread è completata allora non c’è bisogno della risorsa e il thread la rilascia. Dopo aver rilasciato la risorsa, il valore del contatore aumenta di 1.
  • Se un altro thread è in attesa di acquisire una risorsa, il thread acquisirà un permesso in quel momento.
  • Se contatore = 0, il thread non ottiene il permesso di accedere alla risorsa condivisa.

Comprendiamo il funzionamento del semaforo con l’aiuto di un diagramma di flusso.

Java Semaphore

Tipi di semafori

Ci sono quattro tipi di semafori, che sono i seguenti:

  • Semafori di conteggio
  • Semafori limitati
  • Semafori temporizzati
  • Semafori binari

Semafori Java

Discutiamo uno per uno in dettaglio.

Semafori di conteggio

I semafori di conteggio sono usati per risolvere la situazione in cui più di un processo vuole eseguire nella sezione critica, contemporaneamente. Quindi, per superare questo problema, usiamo i semafori di conteggio. Per esempio, consideriamo il seguente frammento di codice.

Vediamo l’implementazione delle semafori di conteggio.

CountingSemaphoresExample.java

Bounded Semaphores

Possiamo impostare il limite superiore utilizzando le semafori limitate. Viene usato al posto dei semafori di conteggio perché i semafori di conteggio non contengono alcun valore limite superiore. Il valore limite superiore denota quanti segnali può memorizzare. Per esempio, considerate il seguente frammento di codice.

Vediamo l’implementazione del semaforo limitato.

BoundedSemaphoresExample.java

Semafori temporizzati

I semafori temporizzati permettono a un thread di funzionare per un determinato periodo di tempo. Dopo un certo tempo, il timer si azzera e rilascia tutti gli altri permessi.

Vediamo l’implementazione dei semafori temporizzati.

TimedSemaphoresExample.java

Semafori binari

I semafori binari sono gli stessi dei semafori di conteggio. Ma ricordate che accetta solo valori binari o 0 o 1. La sua implementazione è facile in confronto ad altri semafori. Se il valore è 1, l’operazione di segnalazione ha successo, fallisce altrimenti.

Vediamo l’implementazione delle semafori binarie.

BinarySemaphoresExample.java

Semaphore in Java

In Java, è un costrutto di sincronizzazione dei thread. Il costrutto utilizza una variabile conosciuta come contatore che controlla l’accesso alla risorsa condivisa. È un tipo di variabile che viene utilizzata per gestire i processi concorrenti e sincronizzarli. È anche usato per evitare condizioni di gara. Limita il numero di threads per accedere ad una risorsa condivisa.

Per esempio, possiamo limitare un file per accedere fino a 10 connessioni simultaneamente.

Classe Java Semaphore

Java fornisce una classe Semaphore per implementare il meccanismo semaforico. Appartiene al pacchetto java.util.concurrent. Implementa l’interfaccia Serializable. Quindi, l’implementazione manuale non è richiesta.

La classe Semaphore fornisce i seguenti due costruttori:

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

Semaphore(int permits)

Crea un Semaphore e analizza il numero di permit (numero iniziale di permit disponibili) come argomento. Specifica il numero di thread che possono condividere una risorsa alla volta. Il valore dei permessi può essere negativo. In tal caso, deve avvenire un rilascio prima che qualsiasi acquisizione sia concessa.

Sintassi:

Semaphore(int permits, boolean fair)

Crea un Semaphore con il numero di permessi dato e le impostazioni di fairness date.

Sintassi:

Esamina due parametri:

  • permits: Il valore dei permessi può essere negativo. In tal caso, il rilascio deve avvenire prima che qualsiasi acquisizione venga concessa.
  • fair: Se impostiamo il valore a true, il semaforo garantisce FIFO ai thread nell’ordine in cui vengono richiesti, false Per impostazione predefinita, tutti i thread che sono in attesa della risorsa concede permessi in un ordine indefinito.

Metodi della classe Semaphore

La classe fornisce i seguenti metodi:

metodoacquire(): Il metodo acquisisce i permessi dal semaforo, bloccando fino a quando uno è disponibile, o il thread viene interrotto. Riduce il numero di permessi disponibili di 1.

Se non c’è nessun permesso disponibile per il thread corrente, il thread diventa disabilitato ai fini della programmazione dei thread. Il thread corrente va nello stato inattivo finché non succede una delle due cose:

  • Se l’altro thread invoca il metodo release() per rilasciare la risorsa allora il thread corrente ottiene i permessi.
  • Se l’altro thread interrompe il thread corrente.

Lancia InterruptedException se il thread corrente viene interrotto. Il metodo non restituisce alcun valore.

Sintassi:

release() Metodo: Rilascia un permesso e lo restituisce al semaforo. Incrementa il numero di permessi disponibili di 1. Se un thread cerca di acquisire un permesso, il semaforo concede il permesso di acquisire la risorsa che è stata appena rilasciata da altri thread. Inoltre, quel thread è considerato ai fini della programmazione dei thread.

Sintassi:

metodo AvailablePermits(): Il metodo restituisce il numero di permessi disponibili nel semaforo per la concessione della risorsa. Di solito, è usato per scopi di debug e test.

Sintassi:

Comprendiamo i metodi di cui sopra attraverso un semplice esempio.

Usare il semaforo come blocco

Java ci permette di usare un semaforo come un blocco. Significa che blocca l’accesso alla risorsa. Ogni thread che vuole accedere alla risorsa bloccata, deve chiamare il metodo acquire() prima di accedere alla risorsa per acquisire il blocco. Il thread deve rilasciare il blocco chiamando il metodo release(), dopo il completamento del compito. Ricordate che impostate il limite superiore a 1. Per esempio, considera il seguente frammento di codice:

Vediamo un esempio di semaforo e usiamo il semaforo come un blocco.

SemaphoreAsLock.java

Output:

Java Semaphore

Nota: Quando eseguiamo il programma sopra, otteniamo un output diverso ogni volta. Quindi, il tuo output potrebbe essere diverso da quello mostrato sopra.

Java Semaphore Example

Comprendiamo il meccanismo del semaforo attraverso un programma Java. Nel seguente esempio, abbiamo creato un costruttore della classe Semaphore con il valore iniziale di permesso 3.

SemaphoreExample.java

Output:

Java Semaphore

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.