Ci sono diversi problemi qui.
Il semplice prima. Sì, leggere e scrivere una variabile booleana è un'operazione atomica. (precisazione: Quello che voglio dire è che la lettura e scrittura da soli sono operazioni atomiche per booleani, non leggere e scrittura, che sarà ovviamente generare due operazioni, che insieme non saranno atomica)
Tuttavia, a meno che non si adottino ulteriori passaggi, il compilatore potrebbe ottimizzare tali operazioni di lettura e scrittura o spostare le operazioni in giro, il che potrebbe far funzionare il codice in modo diverso da quello che si intende.
Marcatura il campo come volatile
significa che le operazioni non saranno ottimizzate di distanza, la direttiva in pratica dice che il compilatore non deve mai assumere il valore in questo campo è lo stesso di quello precedente, anche se è appena letto nel istruzioni precedenti.
Tuttavia, su macchine multicore e multicpu, diversi core e cpu potrebbero avere un valore diverso per il campo nella loro cache, e quindi aggiungere una clausola lock { }
o qualsiasi altra cosa che costringa una barriera di memoria. Ciò assicurerà che il valore del campo sia coerente tra i core. Inoltre, le letture e le scritture non si sposteranno oltre una barriera di memoria nel codice, il che significa che hai la prevedibilità in cui si verificano le operazioni.
Quindi, se sospettate, o sapete, che questo campo verrà scritto e letto da più thread, aggiungo sicuramente il blocco e il volatile al mix.
Nota che non sono esperto di multithreading, sono in grado di tenere il mio, ma di solito programma in modo difensivo. Potrebbe (presumibilmente è altamente probabile) che tu possa implementare qualcosa che non usa un lock (ci sono molti costrutti lock-free), ma purtroppo non sono abbastanza esperto in questo argomento per gestire queste cose. Pertanto, il mio consiglio è di aggiungere sia una clausola lock
sia una direttiva volatile
.
"leggere e scrivere una variabile booleana è un'operazione atomica". ... questo non è vero. Qualcosa di semplice come "booleano a = b" genera 2 istruzioni JVM. – sgp15
Mi dispiace, * leggere * e * scrivere * operazioni da soli sono operazioni atomiche per i booleani, leggere e poi scrivere, è due. Questo è vero per **. NET ** e Java. –