lazySet kann für die rmw-Kommunikation zwischen Threads verwendet werden, da xchg atomar ist. Wenn der Writer-Thread-Prozess eine Cache-Zeilenposition ändert, wird dies vom Prozessor des Reader-Threads beim nächsten Lesen angezeigt, da das Cache-Kohärenzprotokoll der Intel-CPU dies garantiert LazySet funktioniert, aber die Cache-Zeile wird beim nächsten Lesen aktualisiert. Auch hier muss die CPU modern genug sein.
http://sc.tamu.edu/systems/eos/nehalem.pdf
Für Nehalem, eine Multiprozessor-Plattform, haben die Prozessoren die Möglichkeit, den Adressbus für die Zugriffe anderer Prozessoren auf den Systemspeicher und zu überwachen (zu belauschen) zu ihren internen Caches. Sie verwenden diese Snooping-Fähigkeit, um ihre internen Caches sowohl mit dem Systemspeicher als auch mit den Caches in anderen miteinander verbundenen Prozessoren konsistent zu halten. Wenn ein Prozessor durch Snooping erkennt, dass ein anderer Prozessor beabsichtigt, an einen Speicherort zu schreiben, den er derzeit im freigegebenen Zustand zwischengespeichert hat, macht der Snooping-Prozessor seinen Cache-Block ungültig und zwingt ihn, beim nächsten Zugriff auf denselben Speicherort eine Cache-Zeilenfüllung durchzuführen .
Oracle Hotspot JDK für x86-CPU-Architektur->
lazySet == unsafe.putOrderedLong == xchg rw (asm-Anweisung, die als weiche Barriere dient und 20 Zyklen auf nehelem intel cpu kostet)
Auf x86 (x86_64) ist eine solche Barriere in Bezug auf die Leistung viel billiger als flüchtig oder AtomicLong getAndAdd.
In einem Szenario mit einem Produzenten und einer Konsumentenwarteschlange kann xchg soft barriere die Codezeile vor dem lazySet (Sequenz + 1) erzwingen, damit der Produzententhread ausgeführt wird, BEVOR jeder Konsumententhreadcode die neuen Daten verbraucht (bearbeitet) Der Consumer-Thread muss atomar überprüfen, ob die Producer-Sequenz mithilfe eines compareAndSet (Sequenz, Sequenz + 1) um genau eins erhöht wurde.
Ich habe nach dem Hotspot-Quellcode gesucht, um die genaue Zuordnung des lazySet zum cpp-Code zu finden:
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/prims/unsafe. cpp
Unsafe_setOrderedLong -> SET_FIELD_VOLATILE-Definition -> OrderAccess: release_store_fence. Für x86_64 wird OrderAccess: release_store_fence so definiert, dass die Anweisung xchg verwendet wird.
Sie können sehen, wie es in jdk7 genau definiert ist (Doug Lea arbeitet an einigen neuen Dingen für JDK 8):
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/4fc084dac61e/src/os_cpu/ linux_x86 / vm / orderAccess_linux_x86.inline.hpp
Sie können die hdis auch verwenden, um die Assembly des lazySet-Codes in Aktion zu zerlegen.
Es gibt noch eine andere verwandte Frage:
Brauchen wir mfence, wenn wir xchg verwenden?