First post in a long while...
I'd like to know: do Threads blocking on a synchronized method qualify for competing for the monitor in the same way as threads already in the object's wait set?
To make it clearer consider this tiny class:
At our current state of play we have C1 which is the lucky thread with the monitor and it's in the get() method at point X. Thread C2 is blocked on the get method as it can't get the monitor. Threads P1 and P2 have previously gone into the put() method and are now idling in the wait set. Now assume C1 trundles on and calls notify(). Is it possible that the notify call does not wake-up P1 and P2 but in fact the JVM picks C2 to acquire the monitor. It seems to me that it is, as they are all going to compete for the same monitor, however C2 is not technically 'in the wait set', it's blocking, and all the documentation seems to just talk about picking a thread in the wait set and waking it up.
The notify() method will take one of the threads blocking on the wait() call and wake it up. But that thread still has to re-gain the lock, and so will compete with all other threads trying to get the lock. So C2, and either one of the P1 or P2 threads will end up competing for the lock. C2 could take the lock, which would mean the P thread which was notified would still have to block until it gets another chance at the lock.
posted 7 years ago
Thanks for your reply, very concise and clear.
I think this subtlety is missed by a lot of developers as they would erroneously assume that only a thread blocking in wait() would acquire the lock. I guess using synchronized blocks or java.util.concurrent explicit Lock objects would make the syntax less error prone.
My pie came with a little toothpic holding up this tiny ad: