Пытаясь понять, как SubmissionPublisher
( исходный код в Java SE 10, OpenJDK | docs ), новый класс, добавленный в Java SE в версии 9, был реализован, я наткнулся на несколько вызовов API, о которых VarHandle
раньше не знал:
fullFence
, acquireFence
, releaseFence
, loadLoadFence
И storeStoreFence
.
Проведя некоторые исследования, особенно в отношении концепции барьеров / заборов памяти (я слышал о них ранее, да; но никогда не использовал их, поэтому был совершенно незнаком с их семантикой), я думаю, что у меня есть общее представление о том, для чего они , Тем не менее, поскольку мои вопросы могут возникнуть из-за неправильного представления, я хочу убедиться, что я правильно понял в первую очередь:
Барьеры памяти переупорядочивают ограничения относительно операций чтения и записи.
Барьеры памяти можно разделить на две основные категории: однонаправленные и двунаправленные барьеры памяти, в зависимости от того, устанавливают ли они ограничения на чтение или запись, или на то и другое.
C ++ поддерживает множество барьеров памяти , однако они не совпадают с теми, которые предоставляет
VarHandle
. Однако некоторые из имеющихся в наличии барьеров памятиVarHandle
обеспечивают эффекты упорядочения , совместимые с соответствующими им барьерами памяти C ++.#fullFence
совместим сatomic_thread_fence(memory_order_seq_cst)
#acquireFence
совместим сatomic_thread_fence(memory_order_acquire)
#releaseFence
совместим сatomic_thread_fence(memory_order_release)
#loadLoadFence
и не#storeStoreFence
имеют совместимого контраргумента C ++
Слово « совместимость» кажется здесь действительно важным, поскольку семантика явно отличается, когда дело доходит до деталей. Например, все барьеры C ++ являются двунаправленными, в то время как барьеры Java не являются (обязательно).
- Большинство барьеров памяти также имеют эффекты синхронизации. Это особенно зависит от используемого типа барьера и ранее выполненных инструкций барьера в других потоках. Поскольку полное значение, которое имеет инструкция для барьера, зависит от аппаратного обеспечения, я буду придерживаться барьеров более высокого уровня (C ++). Например, в C ++ изменения, сделанные до инструкции барьера освобождения , видны потоку, выполняющему инструкцию барьера получения .
Верны ли мои предположения? Если да, то мои следующие вопросы:
Существуют ли барьеры памяти в
VarHandle
какой-либо синхронизации памяти?Независимо от того, вызывают ли они синхронизацию памяти или нет, для чего могут быть полезны ограничения переупорядочения в Java? Модель памяти Java уже дает некоторые очень строгие гарантии в отношении упорядочения, когда задействованы изменчивые поля, блокировки или
VarHandle
подобные операции#compareAndSet
.
В случае, если вы ищете пример: вышеупомянутый BufferedSubscription
, внутренний класс SubmissionPublisher
(источник связан с выше), установил полный забор в строке 1079 (функция growAndAdd
; поскольку связанный веб-сайт не поддерживает идентификаторы фрагмента, просто CTRL + F для него ). Однако для меня неясно, для чего это.
plain -> opaque -> release/acquire -> volatile (sequential consistency)
.