Строго говоря, я не вижу, чтобы можно было с уверенностью предположить, что для needsGreeting
установлено значение true, когда вызывается greet
.
Чтобы это было правдой, пришлось быБыть до того, как возникнет связь между начальной записью (происходящей, когда объект создается) и первым чтением (в greet
-методе). Глава 17 Потоки и блокировки в JLS, однако, заявляет следующее об ограничениях «происходит до» ( hb ):
17.4.5 Случается-перед заказом Два действия могут быть заказаны с помощью отношения "до того как".Если одно действие происходит раньше другого, то первое видно и упорядочено перед вторым.
Если у нас есть два действия x и y, мы пишем hb (x, y) вуказывает, что x происходит до y.
- Если x и y являются действиями одного и того же потока, а x предшествует y в программном порядке, то hb (x, y) .
- Для этого объекта существует крайний случай "до" от конца конструктора объекта до начала финализатора (§12.6).
- Если действие x синхронизируется сСледующее действие y, тогда мы также имеем hb (x, y) .
- Если hb (x, y) и hb (y, z), затем hb (x, z) .
Кроме того, единственный способ ввести синхронизированное отношение , то есть порядок синхронизации , состоит в следующем::
Действия синхронизации вызывают отношение синхронизации с действиями, определенными следующим образом:
- Действие разблокировки на мониторе m синхронизируется со всеми последующими действиями блокировки на m (где последующие определены в соответствии с порядком синхронизации).
- Запись в энергозависимую переменную (§8.3.1.4) v синхронизирует со всеми последующими чтениями v любым потоком (где последующие определяются в соответствии с синхронизациейorder).
- Действие, которое запускает поток, синхронизируется с первым действием в потоке, которое он запускает.
- Запись значения по умолчанию (ноль, ложь или ноль) для каждой переменной синхронизируется-с первым действием в каждой теме.Хотя может показаться немного странным записать значение по умолчанию в переменную до того, как будет выделен объект, содержащий переменную, концептуально каждый объект создается в начале программы с его инициализированными значениями по умолчанию.
- Последнее действиев потоке T1 синхронизируется с любым действием в другом потоке T2, которое обнаруживает, что T1 завершен.T2 может выполнить это, вызвав T1.isAlive () или T1.join ().
- Если поток T1 прерывает поток T2, прерывание по T1 синхронизируется с любой точкой, где любой другой поток (включая T2) определяет, чтоT2 был прерван (вызван InterruptedException или вызван Thread.interrupted или Thread.isInterrupted).
Нигде не говорится, что "создание объекта происходит до каких-либо вызовов методов объекта. Однако отношение" случай до "утверждает, что для этого объекта существует крайний случай "до" от конца конструктора объекта до начала финализатора (§12.6). , который может быть подсказкой о том, что есть не ребро перед событием от конца конструктора объекта до начала произвольного метода!