lazySet может использоваться для взаимодействия между потоками rmw, поскольку xchg является атомарным, что касается видимости, когда процесс потока записи изменяет местоположение строки кэша, процессор потока чтения увидит это при следующем чтении, потому что протокол согласованности кеша процессора Intel будет гарантировать LazySet работает, но строка кеша будет обновлена при следующем чтении, опять же, CPU должен быть достаточно современным.
http://sc.tamu.edu/systems/eos/nehalem.pdf
Для Nehalem, который является многопроцессорной платформой, процессоры имеют возможность «отслеживать» (подслушивать) адресную шину для доступа других процессоров к системной памяти и в свои внутренние тайники. Они используют эту возможность отслеживания, чтобы поддерживать согласованность своих внутренних кэшей как с системной памятью, так и с кешами других взаимосвязанных процессоров. Если через отслеживание один процессор обнаруживает, что другой процессор намеревается записать в ячейку памяти, которую он в настоящее время кэшировал в общем состоянии, процессор отслеживания аннулирует свой блок кеша, заставляя его выполнить заполнение строки кеша при следующем доступе к той же ячейке памяти. ,
oracle hotspot jdk для архитектуры x86 cpu->
lazySet == unsafe.putOrderedLong == xchg rw (инструкция asm, которая служит мягким барьером на 20 циклов на процессоре nehelem intel)
на x86 (x86_64) такой барьер намного дешевле с точки зрения производительности, чем volatile или AtomicLong getAndAdd,
В сценарии с одним производителем и одним потребителем с очередью мягкий барьер xchg может заставить строку кодов перед lazySet (sequence + 1) для потока-производителя произойти ПЕРЕД любым кодом потока-потребителя, который будет потреблять (работать) с новыми данными, конечно Потребительский поток должен будет атомарно проверить, что последовательность производителя была увеличена ровно на единицу, используя compareAndSet (sequence, sequence + 1).
Я проследил исходный код Hotspot, чтобы найти точное сопоставление lazySet с кодом cpp:
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/prims/unsafe. cpp
Unsafe_setOrderedLong -> определение SET_FIELD_VOLATILE -> OrderAccess: release_store_fence. Для x86_64 OrderAccess: release_store_fence определяется как использование инструкции xchg.
Вы можете увидеть, как это точно определено в jdk7 (Дуг Леа работает над некоторыми новыми вещами для JDK 8):
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/4fc084dac61e/src/os_cpu/ linux_x86 / VM / orderAccess_linux_x86.inline.hpp
вы также можете использовать hdis для разборки сборки кода lazySet в действии.
Есть еще один связанный с этим вопрос:
нужен ли нам mfence при использовании xchg