2015-06-07 2 views
12

Ich sehe, wie Java AtomicInteger intern mit CAS (Compare And Swap) -Operation arbeitet. Wenn mehrere Threads versuchen, den Wert zu aktualisieren, verwendet JVM grundsätzlich den zugrunde liegenden CAS-Mechanismus und versucht, den Wert zu aktualisieren. Wenn das Update fehlschlägt, versuchen Sie es erneut mit dem neuen Wert, aber blockieren Sie nie.Wie funktioniert LongAdder besser als AtomicLong

In Java8 führte Oracle eine neue Klasse LongAdder ein, die unter hohen Ansprüchen besser abschneidet als AtomicInteger. Einige Blog-Posts behaupten, dass LongAdder bessere Leistung bringt, indem sie interne Zellen pflegen - Bedeutet das, dass LongAdder die Werte intern aggregiert und später aktualisiert? Könnten Sie mir bitte helfen zu verstehen, wie LongAdder funktioniert?

+0

http://stackoverflow.com/questions/27628538/multithreading-summing-large-number-of-values-atomically/27628873#27628873 – sol4me

+0

Zuerst Ich glaube, ich Sie falsch verstanden. Ich habe deine Frage noch einmal gelesen, ich denke du hast die Idee richtig verstanden. – aioobe

+0

Danke! Ich bin mehr daran interessiert zu verstehen, wie diese internen Zellen organisiert sind? Sagen Sie, wenn 100 Threads versuchen, den Wert zu aktualisieren, wie viele interne Zellen erstellt und wie sie aktualisiert werden? – Sathish

Antwort

5

Bedeutet das, dass LongAdder die Werte intern aggregiert und später aktualisiert?

Ja, wenn ich Ihre Aussage richtig verstehe.

Jede Cell in einer ist eine Variante einer AtomicLong. Mehrere solcher Zellen zu haben ist eine Möglichkeit, die Konkurrenz auszubreiten und somit den Durchsatz zu erhöhen.

Wenn das Endergebnis (Summe) abgerufen werden soll, addiert es nur die Werte jeder Zelle. http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/f398670f3da7/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java

Insbesondere die Anzahl der Zellen durch die Anzahl der CPUs gebunden ist:

Ein großer Teil der Logik um, wie die Zellen organisiert sind, wie sie zugeordnet sind usw. können in der Quelle zu sehen

/** Number of CPUS, to place bound on table size */ 
static final int NCPU = Runtime.getRuntime().availableProcessors(); 
2

Der Hauptgrund, warum es "schneller" ist, ist seine umstrittene Leistung. Dies ist wichtig, weil:

Unter niedrigen Updatekonflikt haben die beiden Klassen ähnliche Eigenschaften.

Sie eine LongAdder für sehr häufige Updates verwenden würde, in denen Atom CAS und nativer Anrufe Unsafe verursachen würde Konkurrenz. (Siehe source und volatile reads). Nicht cache misses/false sharing auf mehreren AtomicLongs zu erwähnen (obwohl ich noch nicht in der Klasse Layout sieht, nicht genügend Speicherplatz padding zu sein scheint vor dem eigentlichen long Feld.

unter hohen Konkurrenz, erwarteten Durchsatz dieser Klasse deutlich höher ist, auf Kosten der höheren Raumverbrauch.

die Umsetzung Striped64, die daher in den Zellen gehalten werden, für die 64-Bit-Werte. die Werte, die aufgefüllt werden (oder gestreift) ist ein Datenhalter erstreckt Der Name: Jede Operation kann auf dem LongAdder die Sammlung von Werten ändern, die im Striped64 vorhanden sind ention tritt auf, eine neue Zelle wird erstellt und modifiziert, so dass der alte Thread gleichzeitig mit dem konkurrierenden beenden kann. Wenn Sie den endgültigen Wert benötigen, werden die Summen jeder Zelle einfach addiert.

Leider kommt die Leistung mit Kosten, die in diesem Fall Speicher ist (wie oft). Der Striped64 kann sehr groß werden, wenn eine große Menge von Threads und Updates darauf geworfen werden.

Zitat Quelle: Javadoc for LongAdder

Verwandte Themen