1350 Stimmen

Unterschied zwischen "wait()" vs "sleep()" in Java

Was ist der Unterschied zwischen einem wait() und sleep() in Threads?

Ist mein Verständnis richtig, dass ein wait()-ender Thread sich immer noch im Laufmodus befindet und CPU-Zyklen verwendet, während ein sleep()-ender Thread keine CPU-Zyklen verbraucht?

Warum haben wir beide wait() und sleep()?

Wie unterscheidet sich deren Implementierung auf niedrigerer Ebene?

61 Stimmen

Sehr gute Frage. Die Semantik beider ist leicht zu verwechseln.

1 Stimmen

Sehr gute Fragen, aber sie sind 2 in einem. Warum wir beide haben, ist nicht dasselbe wie wie sie auf einer niedrigeren Ebene implementiert werden können (und nicht sind!). Darauf habe ich auch geantwortet.

0 Stimmen

Angenommen ein Thread A befindet sich in einem synchronisierten Block, und während er in der CPU ist, wird dieser Thread einem anderen Thread B übergeben. In welchem Zustand wird Thread A jetzt sein? Werden die anderen Threads, die auf diesem synchronisierten Block warten, jetzt eintreten?

47voto

Premraj Punkte 65511

Unterschied zwischen wait() und sleep()

  • Der grundlegende Unterschied besteht darin, dass wait() eine nichtstatische Methode von Object ist und sleep() eine statische Methode von Thread ist.
  • Der Hauptunterschied besteht darin, dass wait() das Sperren freigibt, während sleep() kein Sperren freigibt, während es wartet.
  • wait() wird für die Inter-Thread-Kommunikation verwendet, während sleep() in der Regel dazu dient, eine Pause in der Ausführung einzuführen.
  • wait() sollte innerhalb einer Synchronisation aufgerufen werden, da sonst eine IllegalMonitorStateException auftritt, während sleep() überall aufgerufen werden kann.
  • Um einen Thread wieder aus wait() zu starten, müssen Sie unendlich oft notify() oder notifyAll() aufrufen. Bei sleep() wird der Thread auf jeden Fall nach einem bestimmten Zeitintervall gestartet.

Ähnlichkeiten

  • Beide setzen den aktuellen Thread in den Zustand Not Runnable.
  • Beide sind native Methoden.

29voto

NguyenDat Punkte 4109

Es gibt einige Unterschiede Schlüssel notizen, die ich nach der Arbeit an warten und schlafen schließen, zuerst einen Blick auf das Beispiel mit wait() und sleep():

Beispiel1: mit warten() und schlafen():

synchronized(HandObject) {
    while(isHandFree() == false) {
        /* Hand ist immer noch beschäftigt mit glücklichem Codieren oder etwas anderem, bitte warten */
        HandObject.wait();
    }
}

/* Sperre bekommen ^^, jetzt bin ich dran, nimm jetzt ein Bier */
while (beerIsAvailable() == false) {
    /* Bier kommt immer noch, nicht verfügbar, Hand hält immer noch das Glas, um Bier zu bekommen,
       lasse die Hand nicht los, um andere Aufgaben auszuführen */
    Thread.sleep(5000);
}

/* Jetzt mein Bier genießen ^^ */
Biere trinken();

/* Ich habe genug getrunken, jetzt kann die Hand mit anderen Aufgaben weitermachen: weiter codieren */
setHandFreeState(true);
synchronized(HandObject) {
    HandObject.notifyAll();
}

Einige wichtige Punkte klären:

  1. Aufruf bei:
    • wait(): Aufruf auf dem aktuellen Thread, der das HandObject-Objekt hält
    • schlafen(): Aufruf auf Thread, der die Aufgabe ausführt, um Bier zu bekommen (ist Klassenmethode, daher Auswirkung auf den aktuellen laufenden Thread)
  2. Synchronisiert:
    • wait(): wenn mehrere Threads auf dasselbe Objekt zugreifen (HandObject) synchronisiert werden (Wenn mehr als ein Thread (Thread führt Codierung aus, Thread führt Bier holen aus) auf dasselbe Objekt HandObject zugreifen müssen)
    • schlafen(): wenn auf eine Bedingung gewartet wird, um fortzufahren (Warten auf verfügbares Bier)
  3. Sperre halten:
    • wait(): gibt die Sperre frei, damit andere Objekte die Chance haben, auszuführen (HandObject ist frei, du kannst andere Aufgaben erledigen)
    • schlafen(): hält die Sperre mindestens t Zeit lang (oder bis zum Unterbrechen) (Meine Aufgabe ist noch nicht beendet, ich halte die Sperre weiter und warte auf eine Bedingung, um fortzufahren)
  4. Aufwachbedingung:
    • wait(): bis zum Aufruf von notify(), notifyAll() vom Objekt
    • schlafen(): bis zur Ablaufzeit oder zum Aufruf von Unterbrechung
  5. Und der letzte Punkt ist Verwendung von wie estani es angibt:

normalerweise verwenden Sie sleep() für Zeitsynchronisation und wait() für die Multi-Thread-Synchronisation.

Bitte korrigieren Sie mich, wenn ich falsch liege.

23voto

Vikas Gupta Punkte 1500

Dies ist eine sehr einfache Frage, da diese Methoden völlig unterschiedlich verwendet werden.

Der Hauptunterschied besteht darin, dass das Freigeben des Schlosses oder Monitors beim Warten verzögert wird, während beim Schlafen kein Schloss oder Monitor freigegeben wird. Warten wird für die Inter-Thread-Kommunikation verwendet, während Schlafen eine Pause in der Ausführung einführt.

Dies war nur eine klare und grundlegende Erklärung, wenn Sie mehr möchten, dann lesen Sie weiter.

Im Falle der wait()-Methode wechselt der Thread in den Wartezustand und kommt nicht automatisch zurück, bis wir die notify()-Methode aufrufen (oder notifyAll() wenn mehr als ein Thread im Wartezustand ist und alle diese Threads weckt). Und Sie benötigen synchronisiertes oder Objektschloss oder Klassenschloss, um auf die Methoden wait() oder notify() oder notifyAll() zuzugreifen. Und noch etwas, die wait()-Methode wird für die Inter-Thread-Kommunikation verwendet, da, wenn ein Thread in den Wartezustand wechselt, Sie einen anderen Thread benötigen, um diesen Thread zu wecken.

Aber im Falle von sleep() handelt es sich um eine Methode, die den Prozess für einige Sekunden oder die gewünschte Zeit anhält. Weil Sie keine notify()- oder notifyAll()-Methode provozieren müssen, um den Thread zurückzubekommen. Oder Sie benötigen keinen anderen Thread, um den Thread zurückzurufen. Wenn Sie also möchten, dass etwas nach einigen Sekunden passiert, wie in einem Spiel, nachdem der Benutzer an der Reihe ist, sollen Sie warten, bis der Computer spielt, dann können Sie die sleep()-Methode erwähnen.

Und noch ein wichtiger Unterschied, der oft in Interviews gefragt wird: sleep() gehört zur Klasse Thread und wait() gehört zur Klasse Object.

Das sind alle Unterschiede zwischen sleep() und wait().

Und es gibt eine Ähnlichkeit zwischen beiden Methoden: sie sind beide überprüfte Anweisungen, daher benötigen Sie ein Try-Catch oder Throws, um auf diese Methoden zuzugreifen.

Ich hoffe, das hilft Ihnen.

17voto

om singh Punkte 171

Quelle : http://www.jguru.com/faq/view.jsp?EID=47127

Thread.sleep() versetzt den aktuellen Thread für eine bestimmte Zeitdauer in den Zustand "Nicht ausführbar". Der Thread behält die Monitore, die er erworben hat - d. h. wenn der Thread sich gerade in einem synchronisierten Block oder einer Methode befindet, kann kein anderer Thread diesen Block oder diese Methode betreten. Wenn ein anderer Thread t.interrupt() aufruft, wird der schlafende Thread aufgeweckt.

Zu beachten ist, dass sleep eine statische Methode ist, was bedeutet, dass sie immer den aktuellen Thread betrifft (denjenigen, der die sleep-Methode ausführt). Ein häufiger Fehler besteht darin, t.sleep() aufzurufen, wobei t ein anderer Thread ist; selbst dann ist es der aktuelle Thread, der schläft, nicht der Thread t.

t.suspend() ist veraltet. Durch die Verwendung davon ist es möglich, einen Thread anzuhalten, der nicht der aktuelle Thread ist. Ein angehaltener Thread behält alle seine Monitore, und da dieser Zustand nicht unterbrechbar ist, besteht die Gefahr von Deadlocks.

object.wait() versetzt den aktuellen Thread in den Zustand "Nicht ausführbar", wie sleep(), aber mit einem Unterschied. Wait wird auf ein Objekt, nicht auf einen Thread, aufgerufen; wir nennen dieses Objekt das "Sperrobjekt". Bevor lock.wait() aufgerufen wird, muss der aktuelle Thread auf dem Sperrobjekt synchronisieren; dann gibt wait() dieses Schloss frei und fügt den Thread der "Warteliste" bei, die mit dem Schloss verbunden ist. Später kann ein anderer Thread auf demselben Sperrobjekt synchronisieren und lock.notify() aufrufen. Dadurch wird der originale wartende Thread aufgeweckt. Im Grunde genommen ist wait()/notify() wie sleep()/interrupt(), nur dass der aktive Thread keinen direkten Verweis auf den schlafenden Thread benötigt, sondern nur auf das gemeinsame Sperrobjekt.

16voto

Itay Maman Punkte 29121

Warten und Schlafen sind zwei unterschiedliche Dinge:

  • In sleep() stoppt der Thread für die angegebene Dauer die Arbeit.
  • In wait() stoppt der Thread die Arbeit, bis das gewartete Objekt benachrichtigt wird, in der Regel von anderen Threads.

0 Stimmen

But you can interrupt a sleeping Thread. In that case wait() is redundant infact it wastes CPU cycles too :-( aber man kann einen schlafenden Thread unterbrechen. In diesem Fall ist wait() tatsächlich überflüssig und verschwendet CPU-Zyklen :-(

10 Stimmen

Warten verschwendet keine CPU-Zyklen.

1 Stimmen

@Peter - Ich glaube schon. Es wartet() auf seinen Anteil an CPU-Zyklen und dann gibt das Betriebssystem die CPU-Zyklen an andere Threads ab. Ich denke, das könnte vom Betriebssystem abhängig sein, bin mir aber nicht sicher.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X