Если obj является локальной переменной, и никакой другой поток не оценивает ее, чтобы получить блокировку для нее , как показано здесь , тогда это не имеет значения.В противном случае это сильно нарушается, и применяется следующее:
(Публикация этого, потому что другие ответы недостаточно сформулированы - «вероятно» здесь недостаточно - и не имеют достаточно деталей.)
Каждый раз, когда поток встречает синхронизированный блок, прежде чем он сможет получить блокировку, он должен выяснить, какой объект ему нужно заблокировать, оценивая выражение в скобках после ключевого слова synchronized.
Если ссылка обновляется после того, как поток оценивает это выражение, поток не может знать об этом.Он продолжит захват блокировки старого объекта, который ранее был идентифицирован как блокировка.В конце концов он входит в синхронизированную блокировку блока для старого объекта, в то время как другой поток (который пытается войти в блок после изменения блокировки) теперь оценивает блокировку как новый объект и входит в тот же блок того же объекта, который содержит новую блокировку,и у вас нет взаимного исключения.
Соответствующий раздел в JLS: 14.19 .Поток, выполняющий синхронизированный оператор:
1) оценивает выражение, затем
2) получает блокировку для значения, к которому вычисляется выражение, затем выполняется
3)блок.
Он не пересматривает этап оценки снова, когда успешно устанавливает блокировку.
Этот код не работает.Не делай этого.Зафиксируйте вещи, которые не меняются.