Пытаясь понять, как SubmissionPublisher
(исходный код в Java SE 10, OpenJDK | docs), новый класс, добавленный в Java SE в версии 9, был реализован, я наткнулся на несколько вызовов API на _ 2_ Раньше я не знал:
fullFence
, acquireFence
, releaseFence
, loadLoadFence
и storeStoreFence
.
После некоторых исследований, особенно в отношении концепции барьеров / ограждений памяти (я слышал о них раньше, да; но никогда не использовал их, поэтому был совершенно не знаком с их семантикой), я думаю, что у меня есть базовое понимание того, для чего они нужны . Тем не менее, поскольку мои вопросы могут возникнуть из-за неправильного представления, я хочу убедиться, что все правильно понял:
Барьеры памяти - это переупорядочивающие ограничения в отношении операций чтения и записи.
Барьеры памяти можно разделить на две основные категории: однонаправленные и двунаправленные барьеры памяти, в зависимости от того, устанавливают ли они ограничения на чтение или запись или и то, и другое.
C ++ поддерживает множество барьеров памяти, однако они не совпадают с предоставлено
VarHandle
. Однако некоторые из барьеров памяти, доступных вVarHandle
, обеспечивают эффекты упорядочения, которые совместимы с соответствующими барьерами памяти C ++.#fullFence
is compatible toatomic_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 ++, например, изменения, внесенные до барьерной инструкции release, видны потоку, выполняющему барьерную инструкцию collect.
Мои предположения верны? Если да, то в результате у меня возникают следующие вопросы:
Вызывают ли имеющиеся в
VarHandle
барьеры памяти какую-либо синхронизацию памяти?Независимо от того, вызывают ли они синхронизацию памяти или нет, для чего могут быть полезны ограничения переупорядочения в Java? Модель памяти Java уже дает очень сильные гарантии в отношении порядка, когда задействованы изменчивые поля, блокировки или
VarHandle
операции, такие как#compareAndSet
.
Если вы ищете пример: вышеупомянутый BufferedSubscription
, внутренний класс SubmissionPublisher
(источник указан выше), установил полный забор в строке 1079 (функция growAndAdd
; поскольку связанный веб-сайт не поддерживает идентификаторы фрагментов, просто CTRL + F за это). Однако мне непонятно, для чего он там нужен.
plain -> opaque -> release/acquire -> volatile (sequential consistency)
. - person Eugene   schedule 08.02.2020