Видны ли действия в синхронизированном блоке другим потокам? - PullRequest
0 голосов
/ 27 марта 2020

Я прочитал это Смежный вопрос , и ответ очень помог, но все еще остается вопрос.

Я слышал, что изменения общих полей в синхронизированном блоке гарантированно видны другие потоки.

Для кодов, подобных этому:

Thread1:

synchronized(lock) {
   obj.field1 = value1;
}

Thread2:

synchronized(lock) {
   System.out.println(obj.field1);
}

Предполагается, что thread1 предшествует thread2, как сказано что в соответствии с Java спецификацией, он может go примерно так:

hb(write to obj.field1 in threadOne, unlock in threadOne) AND 
hb(unlock in threadOne, lock in threadTwo) AND 
hb(lock in threadTwo, read from obj.field in threadTwo)

hb означает случайность в Java спецификации, и это гарантирует видимость.

И поскольку «Если hb (x, y) и hb (y, z), то hb (x, z)», мы получаем:

hb(write to obj.field1 in threadOne, read from obj.field1 in threadTwo) 

Мой вопрос находится на первой строке:

hb(write to obj.field1 in threadOne, unlock in threadOne) 

В Java Спецификации я обнаружил только:

Действие разблокировки на мониторе m синхронизируется со всеми последующими действиями блокировки на m (где «последующие» определяются в соответствии с порядок синхронизации).

Указывает, что действие разблокировки происходит до последующих действий блокировки. Но я не могу найти такие слова, как:

Действие в синхронизированном блоке происходит перед действием разблокировки.

Так ли это правильно? И где я могу найти это?

Ответы [ 2 ]

2 голосов
/ 27 марта 2020

Все действия одного и того же потока упорядочены по отношению к случаю до.

JLS 17.4.5:

Если x и y являются действиями одного потока и x предшествует y в программном порядке, затем hb (x, y).

Также обратите внимание, что случайное время является транзитивным, поэтому, если запись в синхронизированном блоке происходит перед разблокировкой, а разблокировка - перед блокировка в другом потоке, тогда запись происходит перед любым действием в синхронизированном блоке в другом потоке.

0 голосов
/ 27 марта 2020

Лучшее объяснение здесь заключается в том, что действие разблокировки имеет крайний случай «до» с последним действием в потоке. Это называется программным заказом. Это описано в документации

Among all the inter-thread actions performed by each thread t, the program order of t is a total order that reflects the order in which these actions would be performed according to the intra-thread semantics of t.

...