lazySet może być używany do komunikacji między wątkami rmw, ponieważ xchg jest atomowy, jeśli chodzi o widoczność, gdy proces wątku piszącego modyfikuje lokalizację linii pamięci podręcznej, procesor wątku czytnika zobaczy to przy następnym odczycie, ponieważ protokół spójności pamięci podręcznej procesora Intel zagwarantuje LazySet działa, ale linia pamięci podręcznej zostanie zaktualizowana przy następnym odczycie, ponownie procesor musi być wystarczająco nowoczesny.
http://sc.tamu.edu/systems/eos/nehalem.pdf
W przypadku Nehalem, który jest platformą wieloprocesorową, procesory mają możliwość „podsłuchiwania” magistrali adresowej w celu uzyskania dostępu innych procesorów do pamięci systemowej i do ich wewnętrznych pamięci podręcznych. Korzystają z tej możliwości szpiegowania, aby zachować zgodność swoich wewnętrznych pamięci podręcznych zarówno z pamięcią systemową, jak iz pamięcią podręczną innych połączonych ze sobą procesorów. Jeśli podczas podsłuchiwania jeden procesor wykryje, że inny procesor zamierza zapisywać dane w lokalizacji pamięci, która jest obecnie przechowywana w pamięci podręcznej w stanie współdzielonym, procesor szpiegujący unieważni swój blok pamięci podręcznej, zmuszając go do wypełnienia linii pamięci podręcznej przy następnym dostępie do tej samej lokalizacji pamięci .
oracle hotspot jdk dla architektury procesorów x86->
lazySet == unsafe.putOrderedLong == xchg rw (instrukcja asm, która służy jako miękka bariera, kosztująca 20 cykli na procesorze nehelem intel)
na x86 (x86_64) taka bariera jest znacznie tańsza pod względem wydajności niż lotna czy AtomicLong getAndAdd,
W scenariuszu z jednym producentem i jednym konsumentem w kolejce, miękka bariera xchg może wymusić wiersz kodów przed lazySet (sekwencja + 1) dla wątku producenta PRZED jakimkolwiek kodem wątku konsumenckiego, który będzie oczywiście zużywał (pracował) nowe dane Wątek konsumenta będzie musiał niepodzielnie sprawdzić, czy sekwencja producenta została zwiększona o dokładnie jeden przy użyciu funkcji compareAndSet (sekwencja, sekwencja + 1).
Prześledziłem po kodzie źródłowym Hotspot, aby znaleźć dokładne mapowanie lazySet do kodu cpp:
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/prims/unsafe. cpp
Unsafe_setOrderedLong -> SET_FIELD_VOLATILE definicja -> OrderAccess: release_store_fence. W przypadku x86_64 OrderAccess: release_store_fence jest zdefiniowany przy użyciu instrukcji xchg.
Możesz zobaczyć, jak to jest dokładnie zdefiniowane w jdk7 (doug lea pracuje nad nowymi rzeczami dla JDK 8):
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/4fc084dac61e/src/os_cpu/ linux_x86 / vm / orderAccess_linux_x86.inline.hpp
możesz również użyć hdis do dezasemblacji kodu lazySet w akcji.
Jest jeszcze jedno powiązane pytanie:
czy potrzebujemy mfence podczas korzystania z xchg