V Jave sú ostatné základné premenné atómové, okrem 8-bajtových, 64-bitových premenných Long a Double.
Java storage model vyžaduje, aby operácie get aj store boli atómové, ale pre nevolatilné dlhé a dvojité premenné umožňuje JVM rozdeliť 64-bitové čítanie alebo zápis na dve 32-bitové operácie.
Ak čítanie a zápis prebieha na rôznych vláknach, čítanie dlhého nevolatilného typu môže viesť k vysokému počtu 32 bitov jednej hodnoty a nízkym 32 bitom druhej.
Takže aj keď vám na expirovaných dátach nezáleží, nemusí byť bezpečné používať zdieľané, meniteľné dlhé a dvojité premenné v multithreaded programe, pokiaľ nie sú vyhlásené za volatilné alebo chránené zámkom.
Keď už hovoríme o atómových operáciách, znamená to, že čítanie a písanie sú atómové, napríklad i=5; Toto je atómová operácia.
Ak sa však operácia dvoch atómov vykonáva súčasne, nemusí byť nutne atómová, napríklad najprv čítanie a potom zápis, potom je možné, že premenná bola po čítaní upravená.
i++ je taká operácia, najprv číta a potom zapisuje, takže celočíselná premenná je atómová, nie že i++ je atómová operácia.
Keď použijete for(int i=0; i<10000; i++){System.out.print(i)}
Zistíte, že nakoniec nevytlačím 10 000, ale asi 8-9 tisíc.
Ale v prípade viacvláknového spracovania, aj keď je celočíselná premenná atómová, môžu nastať problémy s bezpečnosťou vlákien, čo je problém viditeľnosti vlákien, takže je potrebné pridať volatilný príkaz.
Tento modifikátor je nútená premenná, ktorá sa zakaždým číta z pamäte a nie je uložená v registroch. |