My understanding of Java synchronized() blocks is that, if a thread already owns a lock on an object, it can enter a different block synchronized on the same object (re-entrant synchronization). Underneath, I believe that the JVM uses a reference count to increment/decrement the number of times a thread has acquired a lock, and that the lock is only released when the count is zero.
So my question is, if one encounters a piece of code that looks like this:
synchronized(this)
{
if (condition == WAITING)
{
synchronized(this)
{
condition = COMPLETE;
notify();
try
{
wait();
}
catch(InterruptedException e)
{
}
}
}
else
condition = READY;
}
what specifically happens when wait() is called? Does it merely decrement the count, or does it release the lock regardless of the count?
In the first case, it seems to me that it will produce a deadlock if lock re-entry had occurred, because it will still own the lock and would thus wait forever on another thread which is waiting on it.
In the second case, I can't really see what the point of the second synchronized block is at all.
The documentation for wait() says
"The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution,"
so I think that the second case is the correct one, but I could be wrong. So am I missing something, or have I merely come across a redundant synchronized block that could just as easily be removed from the code?