Why do notify block?
Imagine this scenario:
synchronized(x){ while(x.count < 4) { x.wait();
Imagine now notify in another place without blocking around it:
//... println(x.count); // print 3 x.count++; if(count == 4) x.notify() //...
At first glance, everything always sounds like you would expect.
However, imagine a race condition:
//Thread1 enters here synchronized(x){ while(x.count < 4) { //condition is judged true and thread1 is about to wait //..but..ohh!! Thread2 is prioritized just now ! //Thread2, acting on notify block side, notices that with its current count incrementation, //count increases to 4 and therefore a notify is sent.... //but...but x is expected to wait now !!! for nothing maybe indefinitely ! x.wait(); //maybe block here indefinitely waiting for a notify that already occurred! } }
If we had a way to report this side to notify :
Topic 1: "Humm .. notify , you are pretty, but I just started evaluating my condition ( x.count < 4 ) for true, so please ... don’t be stupid just sending the expected notification (before I let you down my status is pending), otherwise it would be ridiculous for me to wait for things that have already passed "
Thread2: "Alright, alright ... I would put a lock around my logic to stay consistent, to send my notification after , your waiting call will release our shared lock, and thus you will get this notification allowing you to exit your waiting state;) "
Thus, always place the lock on the notify side on the same object that is held on hold in order to avoid this situation and so that the relationship is always consistent.
=> The logic leading to notify and the logic leading to wait should never overlap.
source share