„Hallo, Amigo!“

„Und noch ein paar Details. Nennen wir es praktische Ratschläge.“

„Angenommen, Sie haben eine Methode, die auf etwas wartet und einschläft, bis eine Bedingung erfüllt ist.“

Wenn die Sammlung leer ist, warten wir
public synchronized Runnable getJob()
{
 if (jobs.size() == 0)
  this.wait();

 return jobs.remove(0);
}

„Die Java-Dokumentation empfiehlt sehr eindringlich, die Wait-Methode in einer Schleife aufzurufen:“

Wenn die Sammlung leer ist, warten wir
public synchronized Runnable getJob()
{
 while (jobs.size() == 0)
  this.wait();

 return jobs.remove(0);
}

„Warum? Die Sache ist die: Wenn der Thread aufwacht, bedeutet das nicht, dass die Bedingung erfüllt ist. Vielleicht gab es zwanzig solcher schlafenden Threads. Alle sind aufgewacht, aber nur einer kann die Aufgabe übernehmen.“

„Grob gesagt kann es zu ‚Fehlalarmen‘ kommen. Ein guter Entwickler muss damit rechnen.“

„Ich verstehe. Ist es nicht einfacher, einfach Notify zu verwenden?“

„Was wäre, wenn es mehr als eine Aufgabe in der Liste gäbe? Normalerweise wird die Verwendung von Notify aus Gründen der Optimierung empfohlen. In allen anderen Fällen wird empfohlen, die Methode notifyAll zu verwenden.“

"OK."

„Aber es gibt noch mehr. Erstens kann es eine Situation geben, in der jemand Ihre Klasse erbt, seine eigenen Methoden hinzufügt und auch wait/notifyAll verwendet. Mit anderen Worten, es kann eine Situation geben, in der unabhängige Wait/notifyAll-Paare auf dasselbe Objekt warten und nichts voneinander wissen. Was also tun?“

„Rufen Sie in einer Schleife immer wait auf und prüfen Sie, ob die Beendigungsbedingung der Schleife wahr ist!“

"Richtig. Und um ganz klar zu machen, dass man dem nicht entkommen kann, weisen viele Entwickler darauf hin, dass Threads manchmal von selbst aufwachen. Threads, die garantiert nicht versehentlich aufgeweckt werden. Dies scheint ein Nebeneffekt der Codeoptimierung in a zu sein laufende Java-Maschine.“

„Whoa. Verstanden. Ohne eine Schleife ist die Wartemethode nicht gut.“