lazySet pode ser usado para comunicação entre threads rmw, porque xchg é atômico, quanto à visibilidade, quando o processo de thread do gravador modifica a localização de uma linha de cache, o processador da thread do leitor o verá na próxima leitura, porque o protocolo de coerência do cache da CPU Intel garantirá LazySet funciona, mas a linha do cache será atualizada na próxima leitura, novamente, a CPU precisa ser moderna o suficiente.
http://sc.tamu.edu/systems/eos/nehalem.pdf
Para Nehalem, que é uma plataforma de multiprocessador, os processadores têm a capacidade de "espionar" (espionar) o barramento de endereço para acessos de outros processadores à memória do sistema e para seus caches internos. Eles usam essa capacidade de espionagem para manter seus caches internos consistentes com a memória do sistema e com os caches em outros processadores interconectados. Se, por meio de espionagem, um processador detectar que outro processador pretende gravar em um local da memória que atualmente armazenou em cache no estado compartilhado, o processador de espionagem invalidará seu bloco de cache, forçando-o a realizar um preenchimento de linha de cache na próxima vez que acessar o mesmo local de memória .
oracle hotspot jdk para arquitetura de cpu x86->
lazySet == unsafe.putOrderedLong == xchg rw (instrução asm que serve como uma barreira suave que custa 20 ciclos na CPU Intel Nehelem)
em x86 (x86_64), tal barreira é muito mais barata em termos de desempenho do que volátil ou AtomicLong getAndAdd,
Em um produtor, um cenário de fila de consumidor, a barreira suave xchg pode forçar a linha de códigos antes do lazySet (sequência + 1) para que o encadeamento do produtor aconteça ANTES de qualquer código de encadeamento do consumidor que consumirá (trabalhará) os novos dados, é claro o thread do consumidor precisará verificar atomicamente se a sequência do produtor foi incrementada por exatamente um usando um compareAndSet (sequência, sequência + 1).
Rastreei o código-fonte do Hotspot para encontrar o mapeamento exato do lazySet para o código cpp:
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/prims/unsafe. cpp
Unsafe_setOrderedLong -> definição SET_FIELD_VOLATILE -> OrderAccess: release_store_fence. Para x86_64, OrderAccess: release_store_fence é definido como usando a instrução xchg.
Você pode ver como ele está exatamente definido no jdk7 (doug lea está trabalhando em algumas coisas novas para o JDK 8):
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/4fc084dac61e/src/os_cpu/ linux_x86 / vm / orderAccess_linux_x86.inline.hpp
você também pode usar o hdis para desmontar o assembly do código lazySet em ação.
Há outra questão relacionada:
precisamos de mfence ao usar xchg