Search code examples
javamultithreadingwaitsynchronized

How does 2 thread able to acquire lock after notifyAll?


I was reading about inter thread communication in Java using wait/notify/notifyAll.

I went thru this answer: https://stackoverflow.com/a/36276832

There are 2 threads and 1 main thread. Main thread do notifyAll. It wakes up remaining 2 threads, and both the threads prints

":syncronized block have finished"

But i have read that if 2 threads are waiting for a lock, notifyAll will wake up each thread but lock will be acquired by only 1 thread.

So my question is how come both t1 and t2 thread are completing their execution?

When I change from lock.notifyAll(); to lock.notify();, the Java program never ends.

One thread either of t1/t2 will be in waiting state.

Could somebody please answer. I can explain further my doubt in case not understood clearly.

Problem in easy words: If 2 threads are waiting for same lock and 3rd thread do notifyAll, only one of them gets the lock, the other one remain in waiting state, so in the above case, how come both threads are able to complete execution?


Solution

  • The answer to your questions is hidden in the documentation of the notify() and notifyAll() methods.

    In your particular case the owner of the lock object the one the two threads are being synchronized on is the main thread. When we call the notify() method on the lock object, if you see the doc it says "only single thread" is woken up. Hence you see why the program would hang the second thread is never "notfied" to be woken up. The first thread to release the lock on go into "waiting" state is actually the one that is woken up.

    If you see the documentation of "notifyAll()" it states "Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods." emphasis on "all" means that both the threads of yours that have acquired the lock and waiting to be "notified" are woken up.

    The below is the result when we changed the call from notifyAll() to notify(), the first thread to do the wait is notified in this case.

    Time: Tue Jul 09 12:42:37 CDT 2019;Thread-1:thread goes into waiting state and releases the lock
    Time: Tue Jul 09 12:42:37 CDT 2019;Thread-0:only one thread can be in synchronized block
    Time: Tue Jul 09 12:42:42 CDT 2019;Thread-0:thread goes into waiting state and releases the lock
    Time: Tue Jul 09 12:42:47 CDT 2019;Notifying all
    Time: Tue Jul 09 12:42:47 CDT 2019;Thread-1:thread is awake and have reacquired the lock
    Time: Tue Jul 09 12:42:47 CDT 2019;Thread-1:syncronized block have finished