lazySet peut être utilisé pour la communication inter thread rmw, car xchg est atomique, comme pour la visibilité, lorsque le processus de thread d'écriture modifie un emplacement de ligne de cache, le processeur du thread de lecture le verra à la lecture suivante, car le protocole de cohérence du cache du processeur Intel garantira LazySet fonctionne, mais la ligne de cache sera mise à jour à la prochaine lecture, encore une fois, le processeur doit être suffisamment moderne.
http://sc.tamu.edu/systems/eos/nehalem.pdf
Pour Nehalem qui est une plate-forme multiprocesseur, les processeurs ont la capacité de «fouiner» (espionner) le bus d'adresses pour les accès d'autres processeurs à la mémoire système et dans leurs caches internes. Ils utilisent cette capacité de surveillance pour garder leurs caches internes cohérents à la fois avec la mémoire système et avec les caches dans d'autres processeurs interconnectés. Si, grâce à la surveillance, un processeur détecte qu'un autre processeur a l'intention d'écrire dans un emplacement de mémoire qu'il a actuellement mis en cache dans l'état partagé, le processeur de surveillance invalidera son bloc de cache, le forçant à effectuer un remplissage de ligne de cache la prochaine fois qu'il accédera au même emplacement de mémoire .
oracle hotspot jdk pour architecture cpu x86->
lazySet == unsafe.putOrderedLong == xchg rw (instruction asm qui sert de barrière souple coûtant 20 cycles sur le processeur nehelem Intel)
sur x86 (x86_64) une telle barrière est beaucoup moins chère en termes de performances que volatile ou AtomicLong getAndAdd,
Dans un scénario de file d'attente à un producteur et un consommateur, la barrière souple xchg peut forcer la ligne de codes avant le lazySet (séquence + 1) pour que le thread producteur se produise AVANT tout code de thread consommateur qui consommera (travaillera sur) les nouvelles données, bien sûr Le thread consommateur devra vérifier de manière atomique que la séquence du producteur a été incrémentée d'exactement un en utilisant un compareAndSet (sequence, sequence + 1).
J'ai suivi le code source de Hotspot pour trouver le mappage exact du lazySet au code cpp:
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/prims/unsafe. cpp
Unsafe_setOrderedLong -> Définition SET_FIELD_VOLATILE -> OrderAccess: release_store_fence. Pour x86_64, OrderAccess: release_store_fence est défini comme utilisant l'instruction xchg.
Vous pouvez voir comment il est exactement défini dans jdk7 (doug lea travaille sur de nouveaux éléments pour JDK 8):
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/4fc084dac61e/src/os_cpu/ linux_x86 / vm / orderAccess_linux_x86.inline.hpp
vous pouvez également utiliser hdis pour désassembler l'assembly du code lazySet en action.
Il y a une autre question connexe:
avons-nous besoin de mfence lors de l'utilisation de xchg