Usenet said:
However, I couldn't explain satisfactorily *why* it must be a loop
instead of an if. It's just always written in the books that that is
the way.
There are two problems.
One is that you don't know for sure /why/ your wait has been interrupted, so
you should retest the condition. It may turn out not to be true (if you have
been interrupted for some other reason), in which case you need to go back to
sleep. It may be that in some specific application you could prove to your own
satisfaction that there was /no possible/ way that a thread could be woken up
without the condition it was waiting on being true, but why go to that effort
(and why put everyone who subsequently reads the code to the same effort) ?
Even if you do consider everything in your proof (and get it right) you have
created a fragile system that can easily be broken by subsequent maintenance.
Much better just to stick with the standard idiom which is familiar to most
programmers, and which is known to work.
The other reason is that using notify() rather than notifyAll() is fragile.
You have to be /absolutely sure/ that the thread you are notify()-ing is
actually waiting on the object in question. That can be very difficult,
especially since you can easily get race conditions where the notify() happens
before the point where the other thread enters its wait(). If, as is likely,
you cannot be sure that 1 /specific/ thread is waiting, then you have to use
notifyAll(), and since all the threads that are waiting will wake up, you have
to ensure that all but one of them will go back to sleep again.
Incidentally, you wrote
(For full example
check out any standard Java book that teaches threads).
/THE/ book on Java threads is Doug Lea's "Concurrent Programming in Java" which
includes a full discussion of this point. If you don't have it already then I
advise buying it today[*]. It's invaluable.
([*] and it you do have it already, then I advise reading it today ;-)
-- chris