lazySet può essere utilizzato per la comunicazione tra thread rmw, perché xchg è atomico, per quanto riguarda la visibilità, quando il processo del thread del writer modifica una posizione della riga della cache, il processore del thread del lettore lo vedrà alla lettura successiva, perché il protocollo di coerenza della cache della CPU Intel lo garantirà LazySet funziona, ma la riga della cache verrà aggiornata alla prossima lettura, ancora una volta, la CPU deve essere abbastanza moderna.
http://sc.tamu.edu/systems/eos/nehalem.pdf
Per Nehalem, che è una piattaforma multiprocessore, i processori hanno la capacità di "spiare" (intercettare) il bus degli indirizzi per gli accessi di altri processori alla memoria di sistema e nelle loro cache interne. Usano questa capacità di snooping per mantenere le loro cache interne coerenti sia con la memoria di sistema che con le cache in altri processori interconnessi. Se attraverso lo snooping un processore rileva che un altro processore intende scrivere in una posizione di memoria che ha attualmente memorizzato nella cache in stato Condiviso, il processore snooping invaliderà il blocco della cache costringendolo a eseguire un riempimento della riga della cache la prossima volta che accede alla stessa posizione di memoria .
oracle hotspot jdk per architettura cpu x86->
lazySet == unsafe.putOrderedLong == xchg rw (istruzione asm che funge da barriera morbida che costa 20 cicli su CPU Nehelem Intel)
su x86 (x86_64) tale barriera è molto più economica in termini di prestazioni rispetto a volatile o AtomicLong getAndAdd,
In un produttore, uno scenario di coda consumatore, la barriera morbida xchg può forzare la riga di codici prima del lazySet (sequenza + 1) affinché il thread del produttore avvenga PRIMA di qualsiasi codice del thread del consumatore che consumerà (lavorerà) sui nuovi dati, ovviamente il thread del consumatore dovrà controllare atomicamente che la sequenza del produttore sia stata incrementata esattamente di uno utilizzando un compareAndSet (sequenza, sequenza + 1).
Ho tracciato dopo il codice sorgente di Hotspot per trovare la mappatura esatta del codice lazySet su cpp:
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. Per x86_64, OrderAccess: release_store_fence viene definito utilizzando l'istruzione xchg.
Puoi vedere come è esattamente definito in jdk7 (doug lea sta lavorando su alcune nuove cose per JDK 8):
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/4fc084dac61e/src/os_cpu/ linux_x86 / vm / orderAccess_linux_x86.inline.hpp
puoi anche usare gli hdis per disassemblare l'assembly del codice lazySet in azione.
C'è un'altra domanda correlata:
abbiamo bisogno di mfence quando si usa xchg