Подтвердить что ты не робот

Синхронизированный объект, установленный в null

У меня есть два потока Thread1 и Thread2

//Within Thread1     
synchronized(obj1)  
{  
    obj1 = null;  
}  

//Within Thread2  
synchronized(obj1)  
{  
    do something  
}   

Если jvm сначала выполняет thread1 и устанавливает obj1 в значение null, то thread2 видит это изменение немедленно или ему потребуется время, а jvm все равно может запустить синхронизированный блок thread2, поскольку obj1 еще не null?

4b9b3361

Ответ 1

Это почти наверняка нарушит абстракцию синхронизации - я не уверен, что thread2 увидит это изменение немедленно. Вы никогда не должны изменять ссылку на объект, который вы синхронизируете, а тем более на null, что приведет к NullPointerException при любых дальнейших попытках синхронизации на нем.

Ответ 2

Сначала позвольте мне подчеркнуть, что изменение переменной, используемой для синхронизации, - это ужасно плохое & trade;. obj1 должен быть final и никогда не затрагиваться, если он используется в качестве монитора.

Сказав это, вернитесь к своему вопросу:

Если JVM сначала выполняет Thread1, он синхронизируется на obj1, устанавливает его на null, и поток завершается. Второй поток хочет синхронизировать на obj1, NullPointerException будет выбрано. Поскольку модификация obj1 была выполнена в синхронизированном блоке, гарантируется, что Thread2 увидит обновленное значение (так: NullPointerException гарантировано).

Если Thread1 прерван после получения блокировки на obj1, но прежде чем очистить ссылку, Thread2 закроет obj1 и дождитесь завершения Thread1. Затем он успешно войдет в монитор, потому что объект, ранее ссылающийся на obj1, все еще существует.

Ответ 3

synchronized синхронизирует объект, а не ссылку. Установив для параметра obj1 (reference) значение null, thread2 не может синхронизировать объект, ранее указав на obj1, вместо этого вы получите NullPointerException.

Ответ 4

Быстрое исправление заключается в том, чтобы сделать объект простым массивом из 1 элемента и обратиться к массиву для синхронизации, например,

Объект [] obj1 = {null};

Элемент может быть нулевым, не влияя на существование массива. Конечно, это по-прежнему нарушает "правило" не использовать сам объект в синхронизации, но если ваш код не усложняет ситуацию в другом месте, это быстрое исправление должно работать должным образом.

Ответ 5

Это немедленное изменение. Когда Thread 1 "владеет" блокировкой, он может изменить значение obj1 по желанию. Thread 2 должен ждать, пока Thread 1 освободит блокировку. Он обязательно увидит obj1 == null