Это в основном не ответ, на самом деле (изначально хотел сделать это комментарием, но, как вы видите, это слишком долго). Просто я сам много сомневался в этом, много читал и исследовал, и на данный момент я могу с уверенностью сказать: это сложно. Я даже написал несколько тестов с помощью jcstress , чтобы выяснить, насколько они действительно работают (глядя на сгенерированный код сборки), и хотя некоторые из них так или иначе имеют смысл, тема в целом не значит легко.
Самое первое, что вам нужно понять:
В спецификации языка Java (JLS) нигде не упоминается барьеров . Для java это будет деталь реализации: она действительно действует в терминах , предшествующих семантике . Чтобы иметь возможность правильно указать их в соответствии с JMM (Java Модель памяти), JMM придется изменить довольно много .
Работа в процессе.
Во-вторых, если вы действительно хотите поцарапать поверхность, это самое первое, что нужно посмотреть . Разговор невероятный. Моя любимая часть - это когда Херб Саттер поднимает свои 5 пальцев и говорит: «Вот как много людей могут действительно и правильно с ними работать». Это должно дать вам подсказку о сложности. Тем не менее, есть несколько тривиальных примеров, которые легко обработать asp (например, счетчик, обновляемый несколькими потоками, который не заботится о других гарантиях памяти, но заботится только о том, чтобы он сам увеличивался правильно).
Другой пример - когда (в java) вы хотите, чтобы флаг volatile
управлял потоками для остановки / запуска. Вы знаете, классический:
volatile boolean stop = false; // on thread writes, one thread reads this
Если вы работаете с java, вы знаете, что без volatile
этот код не работает (вы можете прочитать, почему двойная проверка блокировки сломан без него например). Но знаете ли вы, что для некоторых людей, которые пишут высокопроизводительный код, это слишком много? volatile
чтение / запись также гарантирует последовательную согласованность - это имеет некоторые серьезные гарантии, и некоторые люди хотят более слабую версию этого.
Флаг безопасности потока, но не энергозависимый? Да, именно: VarHandle::set/getOpaque
.
И вы бы спросили , почему кому-то это может понадобиться, например? Не всем интересны все изменения, которые поддерживаются volatile
.
Давайте посмотрим, как мы достигнем этого в java. Прежде всего, такие exoti c вещей уже существовали в API: AtomicInteger::lazySet
. Это не указано в модели памяти Java, а не имеет четкого определения ; все еще люди использовали это (LMAX, afaik или это для большего чтения ). ИМХО, AtomicInteger::lazySet
- это VarHandle::releaseFence
(или VarHandle::storeStoreFence
).
Давайте попробуем ответить зачем кому-то нужны эти ?
JMM имеет два основных способа доступа к полю: обычный и изменчивый (что гарантирует последовательную согласованность ). Все эти методы, о которых вы упомянули, предназначены для того, чтобы что-то между этими двумя - освободить / приобрести семантику ; Я полагаю, есть случаи, когда люди на самом деле нуждаются в этом.
Даже больше расслабления от выпуска / приобретения будет непрозрачным , что Я все еще пытаюсь полностью понять,
Таким образом, практический результат (ваше понимание довольно правильно, кстати): если вы планируете использовать это в java - у них нет спецификаций на данный момент, делайте это на свой страх и риск. Если вы действительно хотите понять их, их режимы C ++ эквивалентны для начала.