Синхронное переупорядочение в Java - PullRequest
0 голосов
/ 14 октября 2018

Известно, что JVM не должна переупорядочивать операторы из синхронизированного блока вне синхронизированного блока.Учитывая это, разрешено ли JVM изменять порядок назначения y = 7 после блока synchronized в следующем фрагменте?

x = 5;
y = 7;
synchronized (this) {
    x = 6;
}

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

x = 5;
synchronized (this) {
    x = 6;
    y = 7;
}

Можно утверждать, что, поскольку это действительный порядок, присваивание y не может произойти после блока synchronized, поскольку это нарушитправило, что код из синхронизированного блока не должен переупорядочиваться, чтобы происходить после блока, и вывод, что y происходит до конца синхронизированного блока.

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

Подводя итог, является ли следующий порядок действительным упорядочением первого фрагмента?

x = 5;
synchronized (this) {
    x = 6;
}
y = 7;

Ответы [ 2 ]

0 голосов
/ 14 октября 2018

JLS 17.4.5 :

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

...

  • Если действие x синхронизируется со следующим действием y, то у нас также есть hb (x, y).

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

0 голосов
/ 14 октября 2018

Да, ваши рассуждения ошибочны;это не может произойти.

Вход на монитор похож на volatile load (не совсем правильно, но я понимаю, что так проще - будет вставлено два барьера: LoadLoad|LoadStore) и операции до , который не может пересечь этот барьер.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...