Отношение «происходит до» в модели памяти Java

Что касается JLS ch17 Threads and Locks, в нем говорится: "если произойдет одно действие -перед другим, то первый виден и упорядочен перед вторым"; Я думаю:

(1) Что на самом деле означает фраза «заказано раньше»? Потому что даже если действие_а происходит до действия_b, действие_а может быть выполнено после действия_b в какой-то реализации, верно?

(2) Если действие_а происходит до действия_b, значит ли это, что действие_а НЕ ДОЛЖНО видеть действие_b? Или action_a может видеть или не видеть action_b?

(3) Если действие_а НЕ происходит до действия_b, а действие_b НЕ происходит до действия_а, означает ли это, что действие_а может видеть или не видеть действие_b?

(4) Не могло быть никаких циклических событий раньше, верно?

Любой ответ будет оценен :)


person Kurtt.Lin    schedule 24.12.2014    source источник
comment
Лучшее объяснение, которое я когда-либо читал, это оригинальная статья Лесли Лэмпорта: research.microsoft.com/en-us/um/people/lamport/pubs/   -  person midor    schedule 24.12.2014
comment
@midor Действительно отличная статья; но здесь мы говорим о модели памяти Java, а не о распределенной системе :-p   -  person Kurtt.Lin    schedule 24.12.2014
comment
Да, мы говорим о Java, но отношение «произошло до» — это то, что охватывает практически все разделы CS, где выполняются параллельные операции. Афаик не переопределен для Java, и я бы очень удивился, если бы это было так. Почти все его вопросы касаются отношения «произошло до», так что я все же считаю статью Лэмпорта лучшим источником информации.   -  person midor    schedule 24.12.2014
comment
@midor Если вы внимательно посмотрите на то, о чем вас спрашивают, вы увидите, что ОП не ищет разъяснения того, что означает происходит до, а скорее, как конкретные правила JLS предотвращают неестественные результаты, такие как круговая причинность.   -  person Marko Topolnik    schedule 24.12.2014


Ответы (2)


(1) Что на самом деле означает фраза «заказано раньше»? Потому что даже если действие_а происходит до действия_b, действие_а может быть выполнено после действия_b в какой-то реализации, верно?

Происходит до — это причинно-следственная, а не временная связь. action_a причинно упорядочен перед action_b, независимо от того, выполняется ли он на самом деле до него. На практике, однако, среде выполнения было бы очень трудно поддерживать причинно-следственную связь без временного порядка. Ознакомьтесь с моим более ранним вопросом, в котором подробно рассказывается о предмет причинности.

(2) Если действие_а происходит до действия_b, значит ли это, что действие_а НЕ ДОЛЖНО видеть действие_b? Или action_a может видеть или не видеть action_b?

Существует определенный общий порядок видимости действий друг другу. Это рассматривается в разделе, определяющем правильное выполнение. Таким образом, для любых двух действий a и b либо a отображается для b, либо b на a или ничего из вышеперечисленного. Хорошим чтением, чтобы понять понятие правильного выполнения, является Примеры модели памяти Java: Хороший, плохой и уродливый.

(3) Если действие_а НЕ происходит до действия_b, а действие_b НЕ происходит до действия_а, означает ли это, что действие_а может видеть или не видеть действие_b?

Да и то и другое возможно. В любом случае нет никакой гарантии.

(4) Не могло быть никаких циклических событий раньше, верно?

Happens-before должен налагать частичное упорядочение, а ключевое свойство упорядочения — отсутствие циклов.

person Marko Topolnik    schedule 24.12.2014
comment
Для точки-2. Если действие-а происходит до действия-б, то изменения, сделанные действием-а, должны быть видны действию-б, верно? В противном случае, как сохраняется отношение Происходит до? - person TheLostMind; 24.12.2014
comment
Конечно, это определение случается до. - person Marko Topolnik; 24.12.2014
comment
Я запутался, потому что вы говорите - Следовательно, для любых двух действий a и b либо a видимо для b, либо b для a, либо ничего из вышеперечисленного. :) - person TheLostMind; 24.12.2014
comment
Да, я делаю общее заявление о любых двух действиях. Применительно к нашему случаю это подразумевает ответ на вопрос ОП: правильно, action_a НЕ ДОЛЖЕН видеть action_b. - person Marko Topolnik; 24.12.2014
comment
отличные баллы за (1)(3)(4); они действительно помогают; Я был бы признателен за это :) Что касается пункта 2, ясно, что если действие_а происходит до действия_b, то действие_а ДОЛЖНО быть видимым для действия_b; однако интересно, существует ли гарантия того, что action_b НЕ ДОЛЖЕН быть виден action_a, когда action_a происходит до action_b? Я не смог найти явного утверждения, в котором бы это говорилось; даже в тех правильных исполнениях, которые вы упомянули, я не смог их найти. - person Kurtt.Lin; 25.12.2014
comment
Раздел 17.4.8, Требования к исполнению и причинно-следственной связи, полностью посвящен предотвращению случайных значений, которые могли бы произойти, если бы два действия были видны другому. - person Marko Topolnik; 25.12.2014
comment
Отличное чтение, чтобы понять понятие правильно сформированных казней, это: Примеры моделей памяти Java: хорошие, плохие и уродливые. - person Marko Topolnik; 25.12.2014
comment
@MarkoTopolnik спасибо, что поделились этими примерами модели памяти Java; Я собираюсь копаться в этом. :) - person Kurtt.Lin; 26.12.2014

Что это на самом деле означает, говоря, заказал раньше? Потому что даже если действие_а происходит до действия_b, действие_а может быть выполнено после действия_b в какой-то реализации, верно?

Отношение Происходит до создает барьер памяти, который предотвращает выполнение действия-b до действия-a. Таким образом, некоторые базовые оптимизации JVM не могут применяться. Итак, NO действие-a не может выполняться после или вместе с действием-b.

Если action_a происходит до action_b, означает ли это, что action_a НЕ ДОЛЖЕН видеть action_b? Или action_a может видеть или не видеть action_b?

Это означает, что действие-б должно видеть все изменения, внесенные действием-а.

Если action_a НЕ происходит до action_b, а action_b НЕ происходит до action_a, означает ли это, что action_a может видеть или не видеть action_b?

Происходит до — это транзитивное отношение. Таким образом, если действие-а происходит до действия-б, которое происходит до действия-с... так что до действия-у, а действие-у происходит до действия-z, то действие-а происходит до действия-z.

Отношение «происходит до» гарантирует, что действия, которые следуют за текущим действием, увидят изменения, сделанные текущим действием. Если изменения не видны, то происходит раньше не существует.

Раньше не могло быть никаких циклических событий, верно?

Верно, если действие-а происходит до действия-б, действия-с, действия-d, то ни одно из действий b, c, d не может произойти до действия-а.

Изменить:

JLS говорит: Следует отметить, что наличие отношения «происходит до» между двумя действиями не обязательно означает, что они должны выполняться в этом порядке в реализации. Если изменение порядка приводит к результатам, согласующимся с законным исполнением, оно не является незаконным.. Таким образом, если действие-а имеет отношение происходит до с действием-б, то действие-б может выполняться первым при условии, что финал эквивалентен состоянию, если действие а было выполнено до действия б. Это зависит от реализации. JIT может решить запустить действие-b раньше, чем действие a, при условии, что это изменение порядка не повлияет на конечный результат.

  1. Итак, действие-а независимо от действия-б. по крайней мере теоретически :)

  2. Происходит до определяет последовательные действия. Если действия параллельны, то событие "происходит до" не существует.

Примечание. Вся эта путаница возникает из-за того, что JIT удаляет происходит раньше, если нет зависимости между двумя действиями. Прочтите об анализе побегов.

person TheLostMind    schedule 24.12.2014
comment
Спасибо за ваш быстрый ответ. Но для (1) см. этот пост; для (2) как насчет влияния action_b на action_a? для (3) транзитивность великолепна, но как насчет параллельных действий (отношения не происходят раньше)? - person Kurtt.Lin; 24.12.2014
comment
@ Kurtt.Lin - Проверьте мое редактирование. Также проверьте ответ Марко Топлоника. Он тот, кто научил меня Анализу побега :P - person TheLostMind; 24.12.2014
comment
Я бы не рассматривал какие-либо действия JITC как устранение случается-прежде, потому что это концептуальные отношения, семантические последствия которых должны всегда соблюдаться. Блокировка исключения (я думаю, это то, что вы имеете в виду, когда упоминаете Escape Analysis) не удаляет никаких отношений происходит до --- JITC просто заключает, что может удовлетворить их без каких-либо барьеров памяти. - person Marko Topolnik; 24.12.2014