"Hi, Amigo!"

"And a couple more details. Let's call it practical advice."

"Suppose you have a method that's waiting for something and falls asleep until a condition is satisfied."

If the collection is empty, then we wait
public synchronized Runnable getJob()
{
 if (jobs.size() == 0)
  this.wait();

 return jobs.remove(0);
}

"The Java documentation very insistently recommends calling the wait method in a loop:"

If the collection is empty, then we wait
public synchronized Runnable getJob()
{
 while (jobs.size() == 0)
  this.wait();

 return jobs.remove(0);
}

"Why? The thing is that if the thread wakes up, that doesn't mean that the condition is satisfied. Maybe there were twenty such sleeping threads. All of them woke up, but only one can take the task."

"Roughly speaking, there can be 'false alarms'. A good developer must take this into account."

"I see. Isn't it easier to just use notify?"

"Well, what if there was more than one task in the list? Notify is usually recommended to use for the sake of optimization. In all other cases, it's recommended to use the notifyAll method."

"OK."

"But there's more. First, there may be a situation where someone inherits your class, adds their own methods, and also uses wait/notifyAll. In other words, there may be a situation where independent wait/notifyAll pairs wait on the same object and don't know about each other. So what should you do?"

"Always call wait in a loop and check that the loop's termination condition is true!"

"Right. And to make it quite clear that you can't escape this, many developers point out that sometimes threads wake up by themselves. Threads that are guaranteed to not be awakened accidentally. This seems to be side effect of code optimization in a running Java machine."

"Whoa. Got it. Without a loop, the wait method is no good."