Java: Semaphore vs Synchronized (mutua esclusione) per migliori performance

370 visite

java multithread

In questo articolo vedremo come sostituire nel nostro codice Java i Synchronized con Semaphore (in mutua esclusione) per migliorare le prestazioni della nostra applicazione multithread.

Nota: Parlando di synchronized stiamo andando a trattare situazioni di concorrenza in mutua eslusione o Mutex.

Synchronized

In Java la parola riservata synchronized viene usata per la gestione dei metodi che possono essere richiamati contemporaneamente da più thread. Quindi synchronized garantisce un accesso sincronizzato alle risorse condivise gestite da tali metodi. Infatti il thread che entra nel blocco synchronized l’oggetto su cui agisce viene bloccato (locked) per evitare altri accessi concorrenti.

Un semplice esempio è il seguente:

Semaphore

Un semaforo è un’altra struttura di controllo di concorrenza che, come synchronized, permette di dare, o meno, l’accesso a una risorsa condivisa garantendo mutua esclusione o accesso condiviso a un numero limitato di clienti.

La classe Semaphore (java.util.concurrent.Semaphore) si comporta come un vero e proprio semaforo stradale.

Semaphore ha i metodi acquire() e release(), dove il metodo acquire()serve ad acquisire il lock della risorsa e viene rilasciata tramite il metodo release(). Esistono anche altri metodi, come il tryAcquire() dove il richiedente si pone in attesa per un limite di tempo e poi esce (senza acquisire la risorsa).

Riprendendo il nostro esempio di base avremo:

Possiamo notare che abbiamo usato new Semaphore(1, true);  il secondo parametro serve a rendere il semaforo “fair” ossia il primo thread a entrare sarà il primo ad uscire.

Il metodo synchronized dà ottimi risultati in termini di velocità di esecuzione con 2 o 4 thread rispetto al metodo semaphore.

Ma all’aumentare del numero di concorrenti la velocità diminuisce in modo drastico mentre le performance del semaphore migliorano di gran lunga come possiamo vedere nei grafici Benchmark seguenti:

Synchronization multi threads Synchronization-4-threads Synchronization-8-threads Synchronization-128-threads

Come si vede con 128 threads il metodo synchronized è il peggiore in termini di performance, quindi in un software multithread in cui sono previsti un gran numero di accessi concorrenziali se stiamo utilizzando synchronized potrebbe essere conveniente sostituirlo con la classe semaphore.

fonte: java multithread mutex benchmark

Iscriviti alla newsletter e rimani sempre aggiornato

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *