„Hallo, Amigo!“

„Hallo, Rishi!“

„Ich werde Ihnen die Methoden „ wait “ , „notify “ und „ notifyAll “ der Object-Klasse vorstellen.“

„Heute werden wir sie nur kennenlernen, aber wir kommen später wieder und verbringen mehr Zeit damit.“

"Okay."

„Diese Methoden wurden als Teil des Thread-Synchronisationsmechanismus erfunden.“

„Ich möchte Sie daran erinnern, dass Java über einen integrierten Mechanismus zur Steuerung des Zugriffs auf gemeinsam genutzte Ressourcen (Objekte) von verschiedenen Threads verfügt. Ein Thread kann erklären, dass ein Objekt beschäftigt ist, und andere Threads müssen warten, bis das beschäftigte Objekt freigegeben wird. "

„Ich erinnere mich. Das machst du mit dem synchronisierten Schlüsselwort.“

„Richtig. Normalerweise würde der Code etwa so aussehen:“

public void print()
{
 Object monitor = getMonitor();
 synchronized(monitor)
 {
  System.out.println("text");
 }
}

„Erinnerst du dich, wie das funktioniert?“

„Ja. Wenn zwei Threads gleichzeitig die print()-Methode aufrufen, betritt einer von ihnen den Block mit der Bezeichnung synchronisiert und sperrt den Monitor, sodass der zweite Thread wartet, bis der Monitor freigegeben wird.“

"Richtig. Sobald ein Thread den Block mit der Bezeichnung synchronisiert betritt, wird das Monitorobjekt als beschäftigt markiert und andere Threads müssen auf die Freigabe des Monitorobjekts warten. Dasselbe Monitorobjekt kann in verschiedenen Teilen des Programms verwendet werden. "

„Übrigens, warum haben Sie sich für den Namen Monitor entschieden?“

„Ein Monitor ist das, was man normalerweise ein Objekt nennt, das den Status „Besetzt“ oder „Frei“ speichert.“

„Und hier kommen die Wait- und Notify- Methoden ins Spiel.“

„Eigentlich sind das wirklich die einzigen beiden Methoden. Die anderen sind nur Adaptionen dieser Methoden.“

„Lassen Sie uns nun darüber nachdenken, was die Wartemethode ist und warum wir sie brauchen.

„Manchmal gibt es Situationen in einem Programm, in denen ein Thread einen Block synchronisierten Codes betritt und den Monitor sperrt, aber nicht weitermachen kann, weil einige Daten fehlen. Beispielsweise wurde der Download einer Datei, die verarbeitet werden muss, noch nicht abgeschlossen oder so ähnlich."

„Wir könnten einfach warten, bis die Datei heruntergeladen wird. Sie könnten sie auch einfach mit einer Schleife überprüfen. Wenn die Datei noch nicht heruntergeladen wurde, dann schlafen Sie etwa eine Sekunde lang und prüfen Sie erneut, bis sie heruntergeladen ist.“

"Etwas wie das:"

while(!file.isDownloaded())
{
 Thread.sleep(1000);
}
processFile(file);

„Aber in unserem Fall ist diese Art des Wartens zu teuer. Da unser Thread den Monitor gesperrt hat, müssen auch andere Threads warten, obwohl sie möglicherweise bereits über die benötigten Daten verfügen.“

„Um dieses Problem zu lösen, wurde die Methode wait() erfunden. Diese Methode bewirkt, dass der Thread den Monitor freigibt und den Thread dann „suspendiert“.

„Sie können die Wartemethode eines Monitorobjekts nur aufrufen, wenn der Monitor beschäftigt ist, also nur innerhalb eines synchronisierten Blocks. Wenn dies geschieht, stoppt die Ausführung des Threads vorübergehend und der Monitor wird freigegeben, sodass andere Threads ihn verwenden können.“

„Es kommt oft vor, dass ein Thread in einen synchronisierten Block eintritt und „wait“ aufruft, wodurch der Monitor freigegeben wird.“

„Dann wird ein zweiter Thread eintreten und angehalten, dann ein dritter und so weiter.“

„Und wie wird ein Thread wieder aufgenommen?“

„Dafür gibt es eine zweite Methode: Benachrichtigen.“

„Sie können die notify / notifyAll- Methoden eines Monitorobjekts nur aufrufen, wenn der Monitor beschäftigt ist, also nur innerhalb eines synchronisierten Blocks. Die notifyAll- Methode weckt alle Threads, die auf dieses Monitorobjekt warten.“

„Die notify- Methode ‚freigibt‘ einen zufälligen Thread, aber die notifyAll- Methode gibt alle „eingefrorenen“ Threads dieses Monitors frei.“

„Sehr interessant. Danke, Rishi.“

„Es gibt auch Anpassungen der Methode wait():“

wait()-Methode Erläuterung
void wait(long timeout)
Der Thread „friert ein“, aber er „taut wieder auf“, nachdem er auf die Anzahl der Millisekunden gewartet hat, die der Methode als Argument übergeben wurden.
void wait(long timeout, int nanos)
Der Thread „friert ein“, aber er „taut wieder auf“, nachdem er auf die Anzahl der Nanosekunden gewartet hat, die der Methode als Argument übergeben wurden.

„Wir nennen dies auch ein Warten mit Timeout. Die Methode funktioniert wie ein normales Warten, aber wenn die angegebene Zeit verstrichen ist und der Thread nicht aufgeweckt wurde, weckt er sich selbst auf.“