In the book I'm reading it says:
This technique is needed due to a race condition that would otherwise exist between setting and sending the notification and testing and getting the notification. If the wait() and notify() mechanism were not invoked while holding the synchronization lock, there would be no way to guarantee that the notification would be received.
Don't understand what this exactly means, why can the race condition happen?
EDIT: Hmmmm, I see now that this is possibly a duplicate question of Why must wait() always be in synchronized block , but it seams that the answers focus on making the condition check and going to wait synchronized.
Counterexample from shrini1000:
I can still do something like:
while(!condition) { synchronized(this) { wait(); } }
which means there's still a race between checking the condition and waiting even if wait() is correctly called in a synchronized block. So is there any other reason behind this restriction, perhaps due to the way it's implemented in Java?
The fact that something can be misused is hardly a counterexample.
Java only enforces that
wait()andnotify()are part of a synchronized block (since that's the only way they are supposed to be used), but it's up to you to define the block boundaries.As a counter-counterexample, think about the
finallyblock. Java only enforces that it comes after atryblock, but you're the only one who should know what's supposed to go into thattryblock; you could even leave it empty (which would then miss the very point offinally).