Unterschied zwischen Warten und Schlafen in Java

1. Übersicht

In diesem kurzen Artikel werden wir uns die Standardmethoden sleep () und wait () in Java ansehen und die Unterschiede und Ähnlichkeiten zwischen ihnen verstehen.

2. Allgemeine Unterschiede zwischen Warten und Schlafen

Einfach ausgedrückt ist wait () eine Instanzmethode, die für die Thread-Synchronisation verwendet wird.

Es kann für jedes Objekt aufgerufen werden, wie es direkt in java.lang.Object definiert ist , aber es kann nur von einem synchronisierten Block aufgerufen werden . Es gibt die Sperre für das Objekt frei, sodass ein anderer Thread hineinspringen und eine Sperre erlangen kann.

Andererseits ist Thread.sleep () eine statische Methode, die aus jedem Kontext aufgerufen werden kann. Thread.sleep () pausiert den aktuellen Thread und gibt keine Sperren frei.

Hier ein sehr vereinfachter erster Blick auf diese beiden Kern-APIs in Aktion:

private static Object LOCK = new Object(); private static void sleepWaitExamples() throws InterruptedException { Thread.sleep(1000); System.out.println( "Thread '" + Thread.currentThread().getName() + "' is woken after sleeping for 1 second"); synchronized (LOCK) { LOCK.wait(1000); System.out.println("Object '" + LOCK + "' is woken after" + " waiting for 1 second"); } } 

Wenn Sie dieses Beispiel ausführen, wird die folgende Ausgabe erzeugt:

Thread 'main' wird nach 1 Sekunde Schlaf geweckt

Das Objekt '[E-Mail geschützt]' wird nach 1 Sekunde Wartezeit geweckt

3. Aufwachen Warten und schlafen

Wenn wir die sleep () -Methode verwenden, wird ein Thread nach einem bestimmten Zeitintervall gestartet, sofern er nicht unterbrochen wird.

Für wait () ist der Aufwachvorgang etwas komplizierter. Wir können durch den Aufruf entweder die den Faden wecken notify () oder notifyAll () Methoden auf dem Monitor, der auf gewartet wird.

Verwenden Sie notifyAll () anstelle von notify () , wenn Sie alle Threads aktivieren möchten, die sich im Wartezustand befinden. Ähnlich wie bei der wait () Methode selbst, notify () und notifyAll () haben , von dem synchronisierten Kontext aufgerufen werden.

So können Sie beispielsweise warten :

synchronized (b) { while (b.sum == 0) { System.out.println("Waiting for ThreadB to complete..."); b.wait(); } System.out.println("ThreadB has completed. " + "Sum from that thread is: " + b.sum); }

Und dann, so kann ein anderer Thread den wartenden Thread aufwecken - indem er notify () auf dem Monitor aufruft :

int sum; @Override public void run() { synchronized (this) { int i = 0; while (i < 100000) { sum += i; i++; } notify(); } }

Wenn Sie dieses Beispiel ausführen, wird die folgende Ausgabe erzeugt:

Warten auf den Abschluss von ThreadB…

ThreadB ist abgeschlossen. Die Summe aus diesem Thread lautet: 704982704

4. Fazit

Dies ist eine kurze Einführung in die Semantik von Warten und Schlafen in Java.

Im Allgemeinen sollten wir sleep () verwenden, um die Ausführungszeit eines Threads zu steuern, und wait () auf die Multithread-Synchronisation warten . Natürlich gibt es noch viel mehr zu entdecken - nachdem Sie die Grundlagen gut verstanden haben.

Wie immer können Sie die Beispiele in diesem Artikel auf GitHub nachlesen.