I have two threads Thread1
and Thread2
//Within Thread1
synchronized(obj1)
{
obj1 = null;
}
//Within Thread2
synchronized(obj1)
{
do something
}
If jvm first executes thread1 and sets obj1 to null, then will thread2 see that change immediately or will it take time and jvm could still run the thread2 synchronized block since obj1 is not yet null?
This will almost certainly break the synchronization abstraction -- I wouldn't be confident that
thread2
will see the change immediately. You should never change the reference of the object you're synchronizing on, much less set it tonull
, which will cause aNullPointerException
on any further attempts to synchronize on it.First let me emphasise that modifying a variable that is used for synchronization is a terribly bad thing™.
obj1
should befinal
and never be touched if it is used as a monitor.That being said, back to your question:
If JVM first executes Thread1, it synchronizes on
obj1
, sets it tonull
and the thread exits. The second thread wants to synchronize onobj1
,NullPointerException
will be thrown. Because the modification ofobj1
was made in synchronized block, it is guaranteed that Thread2 will see updated value (so:NullPointerException
is guaranteed).If Thread1 is interrupted after obtaining the lock on
obj1
but before clearing the reference, Thread2 will lock onobj1
and wait until Thread1 finished. Then it will successfully enter the monitor because the object previously referenced byobj1
still exists.synchronized
synchronizes on the object, and not the reference. By settingobj1
(a reference) to null, thread2 can't synchronize on the object formerly pointed to byobj1
, you'll get aNullPointerException
instead.A quick fix is to make the object a simple array of 1 element and refer to the array for synchronization, e.g.,
Object[] obj1 = {null};
The element can be null without impacting the existence of the array. Granted, this still breaks the "rule" of not using the object itself in synchronization, but unless your code complicates matters elsewhere, this quick fix should work as expected.
The change is immediate. When Thread 1 "owns" the lock, it can change the value of obj1 at will. Thread 2 has to wait until Thread 1 releases the lock. It will definitely see obj1 == null