În Java, celelalte variabile de bază sunt atomice, cu excepția variabilelor de 8 octeți și 64 de biți Long și Double.
Modelul de stocare Java necesită ca atât operațiunile de obținere, cât și cele de stocare să fie atomice, dar pentru variabile lungi și duble nevolatile, JVM-ul permite împărțirea unei citiri sau scrieri pe 64 de biți în două operații de 32 de biți.
Dacă citirea și scrierea au loc pe fire diferite, citirea unui tip nevolatil lung poate duce la un număr mare de 32 de biți pentru o valoare și un minim de 32 de biți pentru cealaltă.
Deci, chiar dacă nu te interesează datele expirate, s-ar putea să nu fie sigur să folosești variabile lungi și duble partajate, mutabile într-un program multithreaded, decât dacă acestea sunt declarate volatile sau protejate cu blocare.
Vorbind despre operațiuni atomice, înseamnă că cititul și scrisul sunt atomice, cum ar fi i=5; Aceasta este o operațiune atomică.
Totuși, dacă funcționarea a doi atomi se realizează împreună, nu este neapărat atomică, cum ar fi citirea mai întâi și apoi scrierea, atunci este posibil ca variabila să fi fost modificată după citire.
i++ este o astfel de operație, citiți mai întâi și apoi scrieți, deci variabila întreg este atomică, nu că i++ este o operație atomică.
Când folosești for(int i=0; i<10000; i++){System.out.print(i)}
Vei observa că nu voi tipări 10.000 în final și voi tipări cam 8-9 mii.
Dar în cazul multi-threading-ului, chiar dacă variabila întreagă este atomică, pot apărea probleme de siguranță a firului, ceea ce este o problemă de vizibilitate a firului, așa că trebuie să adaugi o afirmație volatilă.
Acest modificator este o variabilă forțată care este citită din memorie de fiecare dată și nu este stocată în registre. |