Als ich Code gelesen habe, habe ich eine Klasse namens "AtomicReference" getroffen und sie nachgeschlagen.
Laut Referenz (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html)
Atomisch aktualisierte Objektreferenz
Das Ding. Ich weiß nicht, ob dies alles ist, aber wenn Sie gleichzeitig programmieren, behalten Sie die Objekte, die Sie aktualisieren möchten. Das "Syncronize" ist teuer und das "Violatile" -Schlüsselwort bricht, wenn es gleichzeitig geschrieben wird.
volatile
Obwohl entgleist, soll das Schlüsselwort "volatile" sicherstellen, dass sich die Variablenreferenz auf den Hauptspeicher und nicht auf den CPU-Cache bezieht. Variablen ohne dieses Schlüsselwort beziehen sich normalerweise auf den CPU-Cache. In einem System mit mehreren CPUs wird nicht immer auf denselben Wert verwiesen. Wenn Sie also das Schlüsselwort "flüchtig" hinzufügen, verweist es auf den Hauptspeicher, auch wenn die laufende CPU unterschiedlich ist, sodass garantiert auf dasselbe verwiesen wird. Daher wird es auch als "Sichtbarkeitsgarantie" bezeichnet. Übrigens ist die Bedeutung von "flüchtig" leicht zu ändern.
private volatile int counter = 0;
Die Beschreibung auf dieser Seite war übrigens sehr gut zu verstehen. Da es sich um eine Site namens "Java Concurrency" handelt, können Sie andere Artikel erwarten.
AtomicReference
AtmoicReference hingegen ist ein Mechanismus zum Referenzieren und Aktualisieren von mehreren Threads, ohne mit "synchronisiert" zu sperren.
get()
AtomicReference<Integer> atomic = new AtomicReference<>();
System.out.println("atomic: "+ atomic.get());
atomic = new AtomicReference<>(10);
System.out.println("atomic: " + atomic.get());
result
atomic: null
atomic: 10
Wenn Sie den Typ wie folgt angeben, können Sie den Wert beibehalten oder mit der Methode get ()
darauf verweisen. Wenn Sie nichts übergeben, wird der Konstruktor mit "null" initialisiert.
set()
Eine Reihe von Werten.
atomic.set(100);
System.out.println("atomic: " + atomic.get());
result
atomic: 100
getAndUpdate()
Normalerweise denke ich nicht, dass Sie "set ()" so oft verwenden. Wenn es in zwei Threads aktualisiert wird, wird der Wert später aktualisiert. Wenn das in Ordnung ist, ist das in Ordnung. Es gibt also Methoden wie getAndUpdate (). Übergeben Sie einen Lambda-Ausdruck, um ihn basierend auf dem aktuellen Wert zu aktualisieren. Einige Methoden haben die Reihenfolge "Update" und "Get" umgekehrt.
UnaryOperator operator = (v) -> (Integer)v + 1;
System.out.println("atomic getAndUpdate: " + atomic.getAndUpdate(operator));
System.out.println("atomic after getAndUpdate: " + atomic.get());
System.out.println("atomic updateAndGet: " + atomic.updateAndGet(operator));
result
atomic getAndUpdate: 20
atomic after getAndUpdate: 21
atomic updateAndGet: 22
compareAndSet()
Einige Methoden schreiben nur, wenn der Wert erwartet wird. Der Rückgabewert ist "boolean", sodass Sie feststellen können, ob es sich um den erwarteten Wert handelt. Dadurch wird sichergestellt, dass es in keinem anderen Thread aktualisiert wurde.
#Zu diesem Zeitpunkt beträgt der Wert 22
atomic.compareAndSet(23, 100);
System.out.println("compareAndSet maybe not updated: " + atomic.get());
result
compareAndSet maybe not updated: 22
Übrigens gab es eine Methode namens schwachCompareAndSet
, und das Ergebnis war das gleiche. Was ist das? Wenn Sie darüber nachdenken, ist die Implementierung dieselbe wie compareAndSet
bis Java8, und von Java9 scheint sie veraltet zu sein. Vergessen Sie es also.
Reference
Recommended Posts