it-swarm.com.de

Wann muss ich AtomicBoolean in Java verwenden?

Wie kann ich AtomicBoolean verwenden und wozu dient diese Klasse?

204
yart

Wenn mehrere Threads den Booleschen Wert überprüfen und ändern müssen. Beispielsweise:

if (!initialized) {
   initialize();
   initialized = true;
}

Dies ist nicht threadsicher. Sie können das Problem beheben, indem Sie AtomicBoolean verwenden:

if (atomicInitialized.compareAndSet(false, true)) {
    initialize();
}
216
Bozho

Hier sind die Notizen (aus Brian Goetz Buch ), die ich gemacht habe, die Ihnen vielleicht helfen könnten

AtomicXXX-Klassen

  • bereitstellung einer nicht blockierenden Compare-and-Swap-Implementierung

  • Nutzt die Unterstützung durch die Hardware (die CMPXCHG-Anweisung für Intel). Wenn viele Threads in Ihrem Code ausgeführt werden, die diese atomare Parallelitäts-API verwenden, werden sie viel besser skaliert als Code, der die Überwachung/Synchronisierung auf Objektebene verwendet. Da die Synchronisationsmechanismen von Java den Code warten lassen, wenn viele Threads durch Ihre kritischen Abschnitte laufen, wird eine erhebliche Menge an CPU-Zeit für die Verwaltung des Synchronisationsmechanismus selbst aufgewendet (Warten, Benachrichtigen usw.). Da die neue API Hardware-Level-Konstrukte (atomare Variablen) und wartungs- und sperrenfreie Algorithmen verwendet, um die Thread-Sicherheit zu implementieren, wird viel mehr CPU-Zeit für "Aufgaben" aufgewendet als für die Verwaltung der Synchronisation.

  • sie bieten nicht nur einen besseren Durchsatz, sondern sind auch widerstandsfähiger gegen Aktivitätsprobleme wie Deadlock und Prioritätsumkehr.

48

Es gibt zwei Hauptgründe, warum Sie einen atomaren Booleschen Wert verwenden können. Erstens ist es veränderlich, Sie können es als Referenz übergeben und den Wert ändern, der beispielsweise dem Booleschen Wert selbst zugeordnet ist.

public final class MyThreadSafeClass{

    private AtomicBoolean myBoolean = new AtomicBoolean(false);
    private SomeThreadSafeObject someObject = new SomeThreadSafeObject();

    public boolean doSomething(){
         someObject.doSomeWork(myBoolean);
         return myBoolean.get(); //will return true
    }
}

und in der Klasse someObject

public final class SomeThreadSafeObject{
    public void doSomeWork(AtomicBoolean b){
        b.set(true);
    }
}

Noch wichtiger ist jedoch, dass sein Thread sicher ist und Entwicklern, die die Klasse verwalten, anzeigen kann, dass diese Variable voraussichtlich geändert und aus mehreren Threads gelesen wird. Wenn Sie keinen AtomicBoolean verwenden, müssen Sie die verwendete boolesche Variable synchronisieren, indem Sie sie als flüchtig deklarieren oder das Lesen und Schreiben des Felds synchronisieren.

33
John Vint

Die Klasse AtomicBoolean gibt Ihnen einen booleschen Wert, den Sie atomar aktualisieren können. Verwenden Sie diese Option, wenn mehrere Threads auf eine boolesche Variable zugreifen.

In Java.util.concurrent.atomic-Paketübersicht finden Sie eine gute allgemeine Beschreibung der Funktionsweise und Verwendungsmöglichkeiten der Klassen in diesem Paket. Ich würde auch das Buch Java Concurrency in Practice von Brian Goetz empfehlen.

17
Cameron Skinner

Auszug aus dem Paketbeschreibung

Package Java.util.concurrent.atomic description: Ein kleines Toolkit mit Klassen, die die sperrfreie thread-sichere Programmierung für einzelne Variablen unterstützen. [...]

Die Spezifikationen dieser Methoden ermöglichen es Implementierungen, effiziente atomare Anweisungen auf Maschinenebene zu verwenden, die auf modernen Prozessoren verfügbar sind. [...]

Instanzen der Klassen AtomicBoolean, AtomicInteger, AtomicLong und AtomicReference ermöglichen jeweils den Zugriff und die Aktualisierung auf eine einzelne Variable des entsprechenden Typs. [...]

Die Memory-Effekte für Zugriffe und Aktualisierungen von Atomics folgen im Allgemeinen den Regeln für flüchtige Stoffe:

  • get hat den Memory-Effekt, eine flüchtige Variable zu lesen.
  • set hat den Speichereffekt, dass eine flüchtige Variable geschrieben (zugewiesen) wird.
  • weakCompareAndSet liest und schreibt eine Variable atomar und bedingt, ist in Bezug auf andere Speicheroperationen für diese Variable geordnet, verhält sich aber ansonsten wie eine normale nichtflüchtige Speicheroperation.
  • compareAndSet und alle anderen Lese- und Aktualisierungsvorgänge wie getAndIncrement haben den Speichereffekt, dass flüchtige Variablen gelesen und geschrieben werden.
5
OscarRyz