"Hallo Amigo!"

'En nog een paar details. Laten we het praktisch advies noemen.'

"Stel dat je een methode hebt die ergens op wacht en in slaap valt totdat aan een voorwaarde is voldaan."

Is de collectie leeg, dan wachten we
public synchronized Runnable getJob()
{
 if (jobs.size() == 0)
  this.wait();

 return jobs.remove(0);
}

"De Java-documentatie beveelt nadrukkelijk aan om de wait-methode in een lus aan te roepen:"

Is de collectie leeg, dan wachten we
public synchronized Runnable getJob()
{
 while (jobs.size() == 0)
  this.wait();

 return jobs.remove(0);
}

'Waarom? Het punt is dat als de draad ontwaakt, dat niet betekent dat aan de voorwaarde is voldaan. Misschien waren er wel twintig van zulke slapende draden. Ze zijn allemaal wakker geworden, maar er kan er maar één de taak op zich nemen.'

"Grof gesproken kunnen er 'valse alarmen' zijn. Een goede ontwikkelaar moet daar rekening mee houden."

"Ik snap het. Is het niet makkelijker om alleen notificatie te gebruiken?"

"Nou, wat als er meer dan één taak in de lijst stond? Notify wordt meestal aanbevolen om te gebruiken omwille van optimalisatie. In alle andere gevallen wordt aanbevolen om de NotifyAll-methode te gebruiken."

"OK."

"Maar er is meer. Ten eerste kan er een situatie zijn waarin iemand jouw klasse erft, zijn eigen methoden toevoegt en ook wait/notifyAll gebruikt. Met andere woorden, er kan een situatie zijn waarin onafhankelijke wait/notifyAll-paren wachten op hetzelfde object en weten niets van elkaar. Dus wat moet je doen?"

"Bel altijd wachten in een lus en controleer of de beëindigingsvoorwaarde van de lus waar is!"

"Juist. En om duidelijk te maken dat je hier niet aan ontkomt, wijzen veel ontwikkelaars erop dat threads soms vanzelf wakker worden. Threads die gegarandeerd niet per ongeluk worden gewekt. Dit lijkt een neveneffect te zijn van code-optimalisatie in een draaiende Java-machine."

"Ho. Begrepen. Zonder lus is de wachtmethode niet goed."