Ogni volta che viene visualizzata una domanda su SO sulla sincronizzazione Java, alcune persone sono molto ansiose di sottolineare che synchronized(this)
dovrebbe essere evitato. Invece, sostengono, è preferibile un blocco su un riferimento privato.
Alcuni dei motivi indicati sono:
- qualche codice malvagio può rubare il tuo lucchetto (molto popolare questo, ha anche una variante "accidentale")
- tutti i metodi sincronizzati all'interno della stessa classe utilizzano lo stesso blocco esatto, riducendo la velocità effettiva
- stai esponendo (inutilmente) troppe informazioni
Altre persone, incluso me, sostengono che synchronized(this)
è un linguaggio usato molto (anche nelle librerie Java), è sicuro e ben compreso. Non dovrebbe essere evitato perché hai un bug e non hai idea di cosa stia succedendo nel tuo programma multithread. In altre parole: se è applicabile, allora usalo.
Sono interessato a vedere alcuni esempi del mondo reale (niente roba da foobar) in cui this
è preferibile evitare un blocco quando synchronized(this)
farebbe anche il lavoro.
Pertanto: dovresti sempre evitarlo synchronized(this)
e sostituirlo con un lucchetto su un riferimento privato?
Alcune ulteriori informazioni (aggiornate man mano che vengono fornite le risposte):
- stiamo parlando della sincronizzazione dell'istanza
- vengono considerati sia il
synchronized
metodo implicito ( metodi) sia la forma esplicita disynchronized(this)
- se citi Bloch o altre autorità sull'argomento, non tralasciare le parti che non ti piacciono (ad esempio Java efficace, oggetto su Sicurezza thread: in genere è il blocco sull'istanza stessa, ma ci sono eccezioni).
- se hai bisogno di granularità nel tuo blocco diverso da quello
synchronized(this)
fornito,synchronized(this)
non è applicabile, quindi non è questo il problema