LazySet peut être utilisé pour la communication inter-filière rmw, parce que xchg est atomique, comme pour la visibilité, lorsque le processus du fil d'écriture modifie l'emplacement d'une ligne de cache, le processeur du fil de lecture le verra à la prochaine lecture, parce que le protocole de cohérence de cache du processeur intel garantira que 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" (écouter) le bus d'adresses pour les accès des autres processeurs à la mémoire système et à leurs caches internes. Ils utilisent cette capacité d'espionnage pour maintenir la cohérence de leurs caches internes à la fois avec la mémoire système et avec les caches des autres processeurs interconnectés. Si, grâce à cette fonction de 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 un état partagé, le processeur surveillant invalidera son bloc de cache, ce qui l'obligera à remplir une ligne de cache la prochaine fois qu'il accédera au même emplacement de mémoire.
oracle hotspot jdk pour l'architecture x86 cpu->
lazySet == unsafe.putOrderedLong == xchg rw( instruction asm qui sert de barrière souple coûtant 20 cycles sur un cpu intel nehelem)
sur x86 (x86_64), une telle barrière est beaucoup moins coûteuse en termes de performances que volatile ou AtomicLong getAndAdd ,
Dans un scénario de file d'attente avec un producteur et un consommateur, la barrière souple de xchg peut forcer la ligne de codes avant le lazySet(séquence+1) pour le thread du producteur à se produire AVANT tout code du thread du consommateur qui consommera (travaillera sur) les nouvelles données, bien sûr le thread du consommateur devra vérifier atomiquement que la séquence du producteur a été incrémentée d'exactement un en utilisant un compareAndSet (séquence, séquence + 1).
J'ai tracé après le code source de Hotspot pour trouver le mapping 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 de 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 le JDK7 (Doug Lea travaille sur de nouveaux éléments pour le 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 le hdis pour désassembler l'assemblage du code lazySet en action.
Il y a une autre question connexe : A-t-on besoin de mfence quand on utilise xchg ?