Im Buch "Effective Java" heißt es:
Die Sprachspezifikation garantiert, dass das Lesen oder Schreiben einer Variablen atomar ist, es sei denn, die Variable ist vom Typ
long
oderdouble
[JLS, 17.4.7].
Was bedeutet "atomar" im Kontext der Java-Programmierung oder der Programmierung im Allgemeinen?
volatile long
odervolatile double
machen das Lesen atomar und das Schreiben atomar.Antworten:
Hier ist ein Beispiel, weil ein Beispiel oft klarer ist als eine lange Erklärung. Angenommen, es
foo
handelt sich um eine Variable vom Typlong
. Die folgende Operation ist keine atomare Operation:In der Tat wird die Variable unter Verwendung von zwei getrennten Operationen geschrieben: eine, die die ersten 32 Bits schreibt, und eine zweite, die die letzten 32 Bits schreibt. Dies bedeutet, dass ein anderer Thread möglicherweise den Wert von liest
foo
und den Zwischenzustand anzeigt.Um die Operation atomar zu machen, müssen Synchronisationsmechanismen verwendet werden, um sicherzustellen, dass die Operation von jedem anderen Thread aus als eine einzelne atomare Operation (dh nicht in Teile teilbar) betrachtet wird. Das bedeutet, dass jeder andere Thread, sobald die Operation atomar gemacht wurde, entweder den Wert von
foo
vor der Zuweisung oder nach der Zuweisung sieht . Aber niemals den Zwischenwert.Eine einfache Möglichkeit, dies zu tun, besteht darin, die Variable flüchtig zu machen :
Oder um jeden Zugriff auf die Variable zu synchronisieren:
Oder um es durch Folgendes zu ersetzen
AtomicLong
:quelle
"Atomoperation" bezeichnet eine Operation, die aus der Sicht aller anderen Threads augenblicklich zu sein scheint. Sie müssen sich keine Gedanken über einen teilweise vollständigen Vorgang machen, wenn die Garantie gilt.
quelle
Es ist etwas, das "dem Rest des Systems augenblicklich erscheint" und unter die Kategorisierung der Linearisierbarkeit in Rechenprozessen fällt . Um diesen verlinkten Artikel weiter zu zitieren:
So kann es beispielsweise im Kontext eines Datenbanksystems zu "atomaren Commits" kommen, was bedeutet, dass Sie einen Änderungssatz von Aktualisierungen in eine relationale Datenbank übertragen können und diese Änderungen entweder alle oder gar nicht übermittelt werden Fall des Scheiterns, nicht auf dieser Weise Daten nicht beschädigt werden, und Folge von Schlössern und / oder Warteschlangen, die nächste Operation eine andere Schreib- oder ein Lese sein, aber nur nach der Tatsache. Im Zusammenhang mit Variablen und Threading ist dies im Hinblick auf den Speicher ähnlich.
Ihr Angebot hebt hervor , dass dieser Bedarf nicht Verhalten in allen Fällen zu erwarten.
quelle
Ich habe gerade einen Beitrag Atomic vs. Non-Atomic Operations gefunden , der mir sehr hilfreich ist.
quelle
Wenn Sie mehrere Threads haben, die die Methoden m1 und m2 im folgenden Code ausführen:
Sie haben die Garantie, dass jeder Thread-Aufruf
m2
entweder 0 oder 5 lautet.Auf der anderen Seite mit diesem Code (wo
i
ist ein langer):Ein Thread-Aufruf
m2
könnte 0, 1234567890L oder einen anderen zufälligen Wert lesen, dai = 1234567890L
nicht garantiert wird, dass die Anweisung für a atomar istlong
(eine JVM könnte die ersten 32 Bits und die letzten 32 Bits in zwei Operationen schreiben und ein Thread könntei
dazwischen beobachten ). .quelle
In Java treten Lese- und Schreibfelder aller Art außer long und double atomar auf, und wenn das Feld mit dem flüchtigen Modifikator deklariert wird, werden auch long und double atomar gelesen und geschrieben. Das heißt, wir erhalten zu 100% entweder das, was dort war oder was dort passiert ist, und es kann auch kein Zwischenergebnis in den Variablen geben.
quelle