In Java, le altre variabili di base sono atomiche, tranne le variabili di 8 byte e 64 bit di Long e Double.
Il modello di storage Java richiede che sia le operazioni get che quelle di store siano atomiche, ma per variabili lunghe e doppie non volatili, la JVM consente di suddividere una lettura o scrittura a 64 bit in due operazioni da 32 bit.
Se la lettura e la scrittura avvengono su thread differenti, leggere un tipo non volatile lungo può portare a 32 bit alti di un valore e 32 bit bassi dell'altro.
Quindi, anche se non ti interessano i dati scadenti, potrebbe non essere sicuro usare variabili lunghe e doppie condivide, mutabili in un programma multithread, a meno che non siano dichiarate volatili o protette da un lock.
Parlando di operazioni atomiche, significa che leggere e scrivere sono atomici, come i=5; Questa è un'operazione atomica.
Tuttavia, se il funzionamento di due atomi viene eseguito insieme, non è necessariamente atomico, come leggere prima e poi scrivere, quindi è possibile che la variabile sia stata modificata dopo la lettura.
i++ è un'operazione di questo tipo, leggi prima e poi scrivi, quindi la variabile intera è atomica, non che i++ sia un'operazione atomica.
Quando usi for(int i=0; i<10000; i++){System.out.print(i)}
Vedrai che alla fine non stamperò 10.000 copie, e ne stamperò circa 8-9 mila.
Ma nel caso del multithreading, anche se la variabile intera è atomica, potrebbero esserci problemi di sicurezza del thread, che è un problema di visibilità del thread, quindi è necessario aggiungere un'istruzione volatile.
Questo modificatore è una variabile forzata che viene letta dalla memoria ogni volta e non viene memorizzata nei registri. |