In Java sind die anderen Grundvariablen atomar, mit Ausnahme der 8-Byte-64-Bit-Variablen Long und Double.
Das Java-Speichermodell verlangt, dass sowohl Get- als auch Store-Operationen atomar sind, aber für nichtflüchtige Long- und Double-Variable-Operationen erlaubt das JVM, eine 64-Bit-Lese- oder Schreiboperation in zwei 32-Bit-Operationen aufzuteilen.
Wenn Lesen und Schreiben auf verschiedenen Threads erfolgen, kann das Lesen eines nichtflüchtigen Typs Long zu hohen 32 Bit des einen Werts und niedrigen 32 Bit des anderen resultieren.
Selbst wenn dir abgelaufene Daten egal sind, ist es möglicherweise nicht sicher, geteilte, veränderliche Long- und Doppelvariablen in einem Multithread-Programm zu verwenden, es sei denn, sie sind als volatil deklariert oder durch eine Sperre geschützt.
Apropos atomare Operationen bedeutet das, dass Lesen und Schreiben atomar sind, wie i=5; Das ist eine atomare Operation.
Wenn jedoch die Operation von zwei Atomen gleichzeitig ausgeführt wird, ist sie nicht zwangsläufig atomar, wie zum Beispiel zuerst lesen und dann schreiben, sodass es möglich ist, dass die Variable nach dem Lesen modifiziert wurde.
i++ ist eine solche Operation, zuerst gelesen und dann geschrieben, sodass die ganzzahlige Variable atomar ist, nicht dass i++ eine atomare Operation ist.
Wenn du for(int i=0; i<10000; i++){System.out.print(i)}
Du wirst feststellen, dass ich am Ende nicht 10.000 drucke, sondern etwa 8.000 bis 9.000.
Aber im Fall von Multithreading kann es selbst dann, wenn die ganzzahlige Variable atomar ist, Thread-Sicherheitsprobleme geben, was ein Problem mit der Thread-Sichtbarkeit ist, daher muss man eine flüchtige Anweisung hinzufügen.
Dieser Modifikator ist eine erzwungene Variable, die jedes Mal aus dem Speicher gelesen wird und nicht in Registern gespeichert wird. |