AtomicInteger в и установить
В чем разница между lazySet и set способы AtomicInteger? Элемент документация не так уж много можно сказать о lazySet:
в конечном итоге устанавливает заданное значение.
похоже, что сохраненное значение не будет сразу установлено на нужное значение, но вместо этого будет запланировано установить некоторое время в будущем. Но, каково практическое применение этого метода? Какой-нибудь пример?
6 ответов:
цитирую прямо из "JDK-6275329: добавление методов lazySet в атомарные классы":
как, вероятно, последнее небольшое продолжение JSR166 для Mustang, мы добавили "в" метод атомно-классы (AtomicInteger, AtomicReference и т. д.). Это ниша метод иногда полезен при точной настройке кода неблокирующие структуры данных. Семантика такова что запись гарантированно не будет переупорядочена с любым предыдущая запись, но может быть переупорядоченный с последующими операциями (или, что то же самое, может быть не видно другим потокам) до тех пор, пока происходит какое-то другое изменчивое действие записи или синхронизации).
основной вариант использования - для обнуления полей узлов в неблокирующие структуры данных исключительно во избежание долгосрочное удерживание отброса; оно применяется когда безвредно если другие потоки некоторое время видят ненулевые значения, но вы бы например, чтобы гарантировать, что структуры в конечном итоге GCable. В таких случаях, вы можете получить лучшую производительность, избегая затраты на нулевую волатильность-пишите. Есть несколько другие варианты использования в этих строках для без ссылки на основе Атомикс, поэтому метод поддерживается во всех Классы AtomicX.
для людей, которые любят думать об этих операций с точки зрения машина-уровень барьеров на общую мультипроцессоров, в обеспечивает предшествующий барьер магазин-магазин (который либо нет или очень дешево на текущих платформах), но нет барьер магазин-нагрузки (который обычно дорогая часть Летучего-пишите).
В могут быть использованы для урмм Интер-нить общения, потому что обмена является атомарным, а для видимости, когда писатель-нить процесс изменения кэша строке location, читатель потока процессор увидите его на следующей читать, потому что кэш согласованности протоколов процессор Intel гарантируют в строительство, но кэш строки будут обновлены на следующей, опять же, процессор должен быть достаточно современным.
http://sc.tamu.edu/systems/eos/nehalem.pdf Для Нехалема, который является многопроцессорная платформа, процессоры имеют возможность "вынюхивать" (подслушивать) адресную шину для доступа других процессоров к системной памяти и к их внутренним кэшам. Они используют эту возможность отслеживания, чтобы сохранить свои внутренние кэши совместимыми как с системной памятью, так и с кэшами в других взаимосвязанных процессорах. Если посредством отслеживания один процессор обнаруживает, что другой процессор намеревается записать в ячейку памяти, которую он в настоящее время кэшировал в общем состоянии, процессор отслеживания аннулирует его блок кэша, заставляя его выполнять заполнение строки кэша в следующий раз, когда он обращается к той же ячейке памяти.
oracle hotspot jdk для архитектуры процессора x86 ->
lazySet = = небезопасно.putOrderedLong == xchg rw (инструкция asm, которая служит мягким барьером стоимостью 20 циклов на процессоре nehelem intel)
на x86 (x86_64) такой барьер намного дешевле по производительности, чем volatile или AtomicLong getAndAdd,
в одном производителе, один потребительские очередь сценарий, обмена мягкий барьер может заставить кодов до в(последовательность+1) для производителей-нить случится до любого потребителя-нить код, который будет потреблять (работают) новые данные, конечно потребительскими нить нужно проверить атомарно, что продюсер последовательности увеличивается ровно через compareAndSet (последовательность, последовательность + 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 Восемь): 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
более широкое обсуждение происхождения и полезности lazySet и лежащего в основе putOrdered можно найти здесь: http://psy-lob-saw.blogspot.co.uk/2012/12/atomiclazyset-is-performance-win-for.html
подводя итог: lazySet-это слабая Летучая запись в том смысле, что она действует как магазин-магазин, а не забор для загрузки магазина. Это сводится к тому, что lazySet JIT компилируется в инструкцию MOV, которая не может быть переупорядочена компилятором, а затем значительно больше дорогая инструкция, используемая для Летучего набора.
при чтении значения вы всегда в конечном итоге делаете летучее чтение (с атомарным*.GET() в любом случае).
lazySet предлагает одному писателю последовательный изменчивый механизм записи, т. е. совершенно законно для одного писателя использовать lazySet для увеличения счетчика, несколько потоков, увеличивающих один и тот же счетчик, должны будут разрешить конкурирующие записи с использованием CAS, что именно то, что происходит под обложками Atomic* для накаливания.
с Concurrent-atomic package summary
lazySet имеет эффекты памяти записи (назначения) изменчивой переменной за исключением того, что она позволяет переупорядочивать с последующими (но не предыдущими) действиями памяти, которые сами по себе не накладывают ограничений на переупорядочивание с обычными энергонезависимыми записями. Среди других контекстов использования lazySet может применяться при обнулении, ради сбора мусора, ссылки, которая никогда не будет доступна снова.
Если вам интересно о lazySet, то вы должны себе другие объяснения тоже
эффекты памяти для доступа и обновления атомики в целом следуйте правилам для летучих веществ, как указано в разделе 17.4 Java™ спецификации языка.
get имеет эффекты памяти значение переменной volatile.
set имеет эффекты памяти записи (назначения) летучих переменная.
lazySet имеет эффекты памяти записи (назначения) изменчивой переменной за исключением того, что она позволяет переупорядочивать с последующими (но не предыдущими) действиями памяти, которые сами не накладывают переупорядочивание ограничения с обычными энергонезависимыми записями. Среди другого использования контексты, lazySet может применяться при обнулении, ради мусора коллекция, ссылка, которая никогда не будет доступна снова.
weakCompareAndSet атомарно считывает и условно записывает переменную, но не создает никаких событий-до упорядочивания, поэтому обеспечивает никаких гарантий в отношении предыдущих или последующих операций чтения и записи любых переменных, отличных от цели weakCompareAndSet. compareAndSet и все другие операции чтения и обновления, такие как getAndIncrement, имеют эффекты памяти как для чтения, так и для записи изменчивые переменные.
вот это мое понимание, поправьте меня, если я ошибаюсь: Вы можете думать о!--0--> Как" полу " volatile: это в основном энергонезависимая переменная с точки зрения чтения другими потоками, т. е. значение, установленное lazySet, может быть не видно другим потокам. Но он становится изменчивым, когда происходит другая операция записи (может быть из других потоков). Единственное влияние lazySet я могу себе представить
compareAndSet. Так что если вы используетеlazySet(),get()из других потоков все еще может получить старое значение, ноcompareAndSet()всегда будет иметь новое значение, так как это операция записи.
Re: попытка заглушить его -
вы можете думать об этом как о способе обработки изменчивого поля, как если бы оно не было изменчивым для конкретной операции хранения (например: ref = null;).
Это не совсем точно, но этого должно быть достаточно, чтобы вы могли принять решение между "хорошо, мне действительно все равно" и "хм, дайте мне подумать об этом немного".
Comments