Storia della questione:
Con l'arrivo di Java, gli sviluppatori si sono trovati di fronte al problema dell'accesso concorrente a risorse condivise. Per affrontare questo problema, sono stati introdotti primitivi di sincronizzazione di alto livello, il principale dei quali è il modificatore chiave synchronized.
Problema:
Senza sincronizzazione, nelle applicazioni multithread, le risorse condivise possono essere danneggiate: si verifica una data race, e lo stato dell'oggetto diventa imprevedibile.
Soluzione:
synchronized consente di organizzare un monitor per un metodo o un blocco di codice, garantendo l'accesso solo a un thread alla volta nella sezione critica. La sincronizzazione del thread può essere implementata a livello di metodo o di blocco.
Esempio di blocco di un oggetto:
public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } }
I blocchi possono anche essere sincronizzati:
public void safeIncrement() { synchronized(this) { count++; } }
Caratteristiche principali:
Qual è la differenza tra un metodo synchronized e un blocco synchronized?
Un metodo synchronized blocca l'intero metodo per l'oggetto corrente (this) o per la classe (se il metodo è statico). Un blocco consente di sincronizzare solo la parte di codice necessaria e di scegliere qualsiasi oggetto per il blocco.
Possono due thread diversi entrare contemporaneamente in due metodi synchronized diversi dello stesso oggetto?
No, se i metodi sono sincronizzati sullo stesso monitor (this). Se utilizzano monitor diversi, allora sì.
Il modificatore synchronized influisce sulla visibilità delle variabili tra i thread?
Sì, l'ingresso in un blocco synchronized resetta le cache dei thread e aggiorna i valori delle variabili (happens-before relationship).
Uno sviluppatore sincronizza metodi statici di una classe su un oggetto istanza, il che non garantisce correttezza quando si utilizza attraverso diverse istanze.
Pro:
Contro:
Tutti i metodi che utilizzano una risorsa condivisa sono sincronizzati su un unico oggetto-monitor, l'area della sezione critica è minima.
Pro:
Contro: