Welche Operationen in Java gelten als atomar?


Antworten:


100
  • alle Zuordnungen primitiver Typen mit Ausnahme von long und double
  • alle Zuordnungen von Referenzen
  • alle Zuordnungen flüchtiger Variablen
  • Alle Operationen der Klassen java.concurrent.Atomic *

und vielleicht noch etwas mehr. Schau dir die jls an .

Wie in den Kommentaren erwähnt, bedeutet Atomizität keine Sichtbarkeit. Während ein anderer Thread garantiert keinen teilweise geschriebenen Thread sieht int, wird er möglicherweise nie den neuen Wert sehen.

Die Operationen auf Long und Double werden auch auf herkömmlichen 64-Bit-CPUs atomar ausgeführt , obwohl keine Garantie besteht. Siehe auch diese Funktionsanforderung .


21
Zuweisungen zu volatileLongs und Doubles sind garantiert atomar: java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7
Joonas Pulakka

11
Auch bedenken , dass , während die Operationen atomar sind, die Sichtbarkeit dieser Vorgänge möglicherweise nicht in einer Multithread - Anwendung gewährleistet werden , wenn nicht besondere Sorgfalt (die Details hier sind Art und Weise , um zu komplizierte in einem Kommentar zu beschreiben ..)
nos

5
64 bit jvm, long and double assignments are also atomic.Bist du sicher? Ich würde sagen, sie sind für kompilierten Code, aber was ist mit interpretiertem Code? Wahrscheinlich hast du recht, aber gibt es eine Garantie?
Maaartinus

4
Die Spezifikation schreibt immer noch nicht vor, dass 64-Bit-JVMs langen und doppelten Zuweisungen Atomizität verleihen. java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7 In seinen berühmten Worten "dieses Verhalten ist implementierungsspezifisch". Höchstwahrscheinlich würden 64-Bit-VMs dies jedoch als atomare Operation implementieren.
sjlee

1
IMHO sind normale Referenzzuweisungen atomar, aber AtomicReference bietet mehr: compareAndSet und getAndSet, was Sie ohne Synchronisation sonst nicht erreichen könnten.
Maaartinus

5

In Java ist das Lesen und Schreiben von 32-Bit- oder kleineren Mengen garantiert atomar.
Mit atomar ist gemeint, dass jede Aktion in einem Schritt stattfindet und nicht unterbrochen werden kann. Wenn wir also Multithread-Anwendungen haben, sind die Lese- und Schreibvorgänge threadsicher und müssen nicht synchronisiert werden.

Der folgende Code ist beispielsweise threadsicher:

public class ThreadSafe   
  {  
    private int x;  
    public void setX(int x)  
          {
           this.x = x;
           } 
  }

5
..threadsafe in dem Sinne, dass der Wert immer entweder genau der ursprüngliche Wert oder der eingestellte Wert ist. Der aktuellste Wert ist für andere Threads aufgrund des Fehlens von "flüchtig" oder "synchronisiert" immer noch nicht sichtbar.
Mikko Wilkman

1
+1 zu dem, was @MikkoWilkman sagt. Dieser Code sollte nicht verwendet werden, da er aus Sicht der Speichersichtbarkeit definitiv nicht threadsicher ist.
Knuckles the Echidna

0

Es scheint, dass Zuweisungen von Longs atomar sind, basierend auf dieser Methode in AtomicLong.java:

public final void set(long newValue) {
    value = newValue;
}

Beachten Sie das Fehlen einer Synchronisation.


3
Schauen Sie sich die Erklärung von an value. Es ist volatile.
Maaartinus

2
Das valueheißt volatile, die Zuordnung von valueAtomic wird nicht vorgenommen, sondern lediglich "Veröffentlichungsprobleme" vermieden.
Lyle Z

7
Es macht beides, siehe JLS, Abschnitt 17.7 : Schreiben und Lesen von flüchtigen Long- und Double-Werten sind immer atomar.
Maaartinus

@LyleZ der wertvollste Kommentar in diesem Thread, meiner Meinung nach.
stdout
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.