In Java, quando è possibile "allontanarsi" se non si utilizzano sincronizzati su variabili che sono in lettura/scrittura per più thread simultanei?Quando è sicuro non sincronizzare le variabili di lettura/scrittura?
Ho letto di un paio di sorprendenti bug di concorrenza: double-checked-locking e hash-maps e ho sempre utilizzato la sincronizzazione per impostazione predefinita in casi di lettura/scrittura condivisi, tuttavia, ho iniziato a chiedermi quando è OK non farlo.
Per esempio, che tipo di regole generali posso usare per decidere quando è realtà sicuro di omettere synchronized
dai metodi come questo:
T getFoo() {
if (this.foo == null) {
this.foo = createFoo() // createFoo is always thread safe.
}
return this.foo;
}
Dove:
T
potrebbe essere primitivi o oggetti arbitraricreateFoo
è sempre thread-safe e può essere chiamato più volte, ma è altrimenti unsp ecified.getFoo()
può essere "alla fine coerente".
Va bene se T sono primitive come int
? Che mi dici di Integer
? Che dire degli oggetti semplici, come String? Etc.
Non è mai giusto non farlo, a meno che non si può in qualche modo semanticamente garanzia che non sarà la lettura e la scrittura allo stesso tempo (o se non si importa se alcuni dei vostri lavoratori stanno leggendo il torto cosa dopo che è stato aggiornato) –
Solo se si sa in qualsiasi momento, ci sarà solo un thread per accedervi. – sauumum
* Non c'è ** nessuna garanzia ** che il valore sarà visto da ** qualsiasi ** thread dopo che è stato aggiornato * senza la sincronizzazione appropriata ('synchronized' è un metodo comune, ma non l'unico). La sicurezza del filo è più di semplici istruzioni/programmi interlacciati. – user2864740