Unterschied zwischen wait () und sleep ()


1204

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

Verstehe ich, dass sich ein wait()-ing-Thread noch im laufenden Modus befindet und CPU-Zyklen verwendet, ein sleep()-ing jedoch keine korrekten CPU-Zyklen verbraucht?

Warum haben wir beide wait() und sleep(): Wie variiert ihre Implementierung auf einer niedrigeren Ebene?


50
sehr gute Frage. Die Semantik beider ist leicht zu verwechseln.
Andreas Petersson

1
Sehr schöne 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!). Darauf habe ich auch geantwortet.
Estani

Angenommen, ein Thread A befindet sich in einem synchronisierten Block, und während er sich in der CPU befindet, wird dieser Thread entnommen und einem anderen Thread B übergeben. In diesem Zustand, in dem Thread A ausgeführt wird, werden die anderen Threads, die auf diesen synchronisierten Block warten, jetzt hineingelangen ?
Peter

1
Hier ist ein guter Artikel, der es beschreibt: qat.com/using-waitnotify-instead-thread-sleep-java
Triton Man

3
seine excatly das Gegenteil - Schlaf „uses“ alle seine verfügbaren CPU-Zyklen , aber da der Faden in „WAITING“ sein wird -state diese können bei Bedarf nachgegeben werden - in der Tat die meisten Betriebssysteme automatisch die Zyklen ergeben IF es möglich ist, damit Ihr Thread erzeugt keine tatsächliche CPU-Auslastung. Dies ist jedoch auf älteren Betriebssystemen der Fall. Object.wait (), auf der anderen Seite nie verwendet keine Zyklen (während sie nicht angemeldete) , weil das ist über Software-Interrupts in vielen Fällen realisiert - privat, transiente & transparent Schleusen, durch die JVM implementiert. Thread.sleep ist eine schlechte Praxis.
Spezialisiert

Antworten:


838

A waitkann von einem anderen Thread "geweckt" werden, der notifyden Monitor aufruft, auf den gewartet wird, während a sleepdies nicht kann. Außerdem muss ein wait(und notify) in einem Block synchronizedauf dem Monitorobjekt vorkommen, während sleepdies nicht der Fall ist:

Object mon = ...;
synchronized (mon) {
    mon.wait();
} 

Zu diesem Zeitpunkt wartet der aktuell ausgeführte Thread und gibt den Monitor frei . Ein anderer Thread kann dies tun

synchronized (mon) { mon.notify(); }

(auf demselben monObjekt) und der erste Thread (vorausgesetzt, es ist der einzige Thread, der auf dem Monitor wartet) werden aktiviert.

Sie können auch anrufen, notifyAllwenn mehr als ein Thread auf dem Monitor wartet - dies weckt alle auf . Es kann jedoch nur einer der Threads den Monitor greifen (denken Sie daran, dass sich der waitin einem synchronizedBlock befindet) und weitermachen - die anderen werden dann blockiert, bis sie die Sperre des Monitors erreichen können.

Ein weiterer Punkt ist , dass Sie rufen Sie waitan Objectsich selbst (dh Sie auf ein Objekt des Monitors warten) , während Sie rufen sleepauf Thread.

Noch ein weiterer Punkt ist , dass man bekommen kann unechte Wakeups aus wait(dh der Faden, der Lebensläufe ohne ersichtlichen Grund wartet). Sie sollten immer waitunter bestimmten Bedingungen wie folgt drehen :

synchronized {
    while (!condition) { mon.wait(); }
}

131
Nein, ich kann nicht. Es kann nur unterbrochen werden.
Peter Štibraný

9
Wenn Sie unterbrechen, müssen Sie wissen, welchen Thread Sie unterbrechen möchten. Wenn Sie notify aufrufen, benötigen Sie nur ein Objekt, und es ist Ihnen egal, ob ein anderer Thread auf dieses Objekt wartet. wait / notify wird für die Kommunikation verwendet, während sleep für das Schlafen verwendet wird.
Peter Štibraný

28
@Geek - warum in aller Welt sagen Sie, dass wait () CPU-Zyklen verschwendet?
Robert Munteanu

25
Eine Unterbrechung ist als Mechanismus gedacht, um einen Thread sanft dazu zu ermutigen, nicht mehr vollständig zu laufen und verbleibende Vorgänge abzubrechen. wait/ notifywerden normalerweise verwendet, um auf einen anderen Thread zu warten, um eine Aufgabe auszuführen, oder um zu warten, bis eine bestimmte Bedingung erfüllt ist.
Louis Wasserman

13
Ich habe alle Antworten durchgelesen, aber mir fehlen immer noch Informationen. Viele Leute haben die Definitionen aus dem Javadoc und auch die Bedeutung der beiden englischen Wörter aufgeschrieben, aber ich verstehe nicht, warum ich jemals Schlaf verwenden sollte, anstatt zu warten? Was ist das Benchmarking und der Geschwindigkeitsunterschied zwischen den beiden? Wenn ich alles kann, was ich mit Schlaf machen kann, warum sollte ich dann jemals Schlaf wählen?
Balazs Zsoldos

334

Ein wesentlicher Unterschied noch nicht erwähnt ist , dass während ein Thema Schlafen nicht nicht Arretierungen es hält, während des Wartens auf die Sperre auf das Objekt , das wait()aufgerufen wird.

synchronized(LOCK) {
    Thread.sleep(1000); // LOCK is held
}


synchronized(LOCK) {
    LOCK.wait(); // LOCK is not held
}

105
Durch das Warten wird nur die Sperre für das Objekt aufgehoben, für das Sie wait () aufrufen . Es werden keine weiteren Sperren freigegeben .
Jon Skeet

16
Sie müssen den Schlaf nicht innerhalb eines Schlosses aufrufen - Sperren und Warten / Benachrichtigen gehen Hand in Hand, aber Sperren und Schlaf hängen nicht zusammen.
oxbow_lakes

7
@oxbow_lakes - Ich würde sagen, dass Sie nicht mit Schlössern schlafen sollten, dafür gibt es nur wenige Anwendungsfälle. Ich wollte nur auf die Unterschiede hinweisen.
Robert Munteanu

5
@RobertMunteanu, Ihre Antwort behauptet misleadingly dass sleephält Java Schlösser, aber es funktioniert nicht. Um einen fairen Vergleich zu haben, würden wir vergleichen synchronized(OUTER_LOCK){ Thread.sleep(1000); }mit synchronized(OUTER_LOCK){ synchronized(LOCK){LOCK.wait();} }und wir können sehen , dass beide Befehle nicht loslassen das OUTER_LOCK. Wenn es einen Unterschied gibt, können wir sagen, dass Java- Sperren sleepnicht explizit verwendet werden , aber die Frage lautet: "Wie variiert ihre Implementierung auf einer niedrigeren Ebene?" unquote.
Pacerier

2
@Pacerier wait()ist mit dem Zustand der innersten Sperre verbunden, von der aus es aufgerufen wird. In Ihrem Codebeispiel wait()kann es nur freigegeben werden LOCKund nicht OUTER_LOCK. So ist der Java-Monitor sowieso aufgebaut. Ein fairer Vergleich wäre synchronized(OUTER_LOCK){ synchronized(LOCK) { Thread.sleep(1000); } }und synchronized(OUTER_LOCK){ synchronized(LOCK) { LOCK.wait(); } }. In diesem Fall sleep()beiden Schlösser halten wird , während wait()freigeben wird , LOCKaber immer noch haltenOUTER_LOCK
Danze

243

Ich fand diesen Beitrag hilfreich. Es stellt den Unterschied zwischen Thread.sleep(), Thread.yield()undObject.wait() in menschlicher Hinsicht. Zitieren:

Alles gelangt schließlich zum Scheduler des Betriebssystems, der Zeitscheiben an Prozesse und Threads verteilt.

sleep(n)sagt: "Ich bin mit meiner Zeitscheibe fertig und bitte gib mir für mindestens n Millisekunden keine weitere."Das Betriebssystem versucht nicht einmal, den Ruhezustandsthread zu planen, bis die angeforderte Zeit abgelaufen ist.

yield()sagt: "Ich bin mit meiner Zeitscheibe fertig, aber ich habe noch Arbeit zu erledigen."Dem Betriebssystem steht es frei, dem Thread sofort eine andere Zeitscheibe zu geben oder einem anderen Thread zu geben oder die CPU zu verarbeiten, die den gerade aufgegebenen Thread ergibt.

wait()sagt: „Ich bin mit meiner Zeitscheibe fertig. Gib mir keine weitere Zeitscheibe, bis jemand notify () anruft. “ Wie beisleep() versucht das Betriebssystem nicht einmal, Ihre Aufgabe zu planen, es sei denn, jemand ruft an notify()(oder eines der wenigen anderen Aufweckszenarien tritt auf).

Threads verlieren auch den Rest ihrer Zeitscheibe, wenn sie blockierende E / A ausführen und unter einigen anderen Umständen. Wenn ein Thread die gesamte Zeitscheibe durchläuft, übernimmt das Betriebssystem die Kontrolle ungefähr so, als obyield() sie aufgerufen worden wäre, damit andere Prozesse ausgeführt werden können.

Sie selten benötigen yield(), aber wenn Sie eine rechenlastige App mit logischen Aufgabe Grenzen haben, ein Einsetzen yield() könnte Reaktionsgeschwindigkeit des Systems verbessern (auf Kosten der Zeit - Kontextwechsel, auch nur auf das Betriebssystem und zurück, sind nicht frei). Messen und testen Sie wie immer anhand von Zielen, die Ihnen wichtig sind.


Der Ertrag ist grundsätzlich plattformabhängig ... javamex.com/tutorials/threads/yield.shtml
Pacerier

Die Erklärung von sleep(n)besagt implizit, dass der aktuell ausgeführte Thread den Monitor der Sperre freiwillig aufgibt, was nicht der Fall ist . Zitat aus Threads Javadoc : "Der Thread verliert nicht den Besitz von Monitoren."
Clint Eastwood

2
@ Jonathan In der Antwort werden Monitore nicht erwähnt, und das liegt daran, dass sleepsie kein spezielles Verhalten in Bezug auf den Monitor aufweisen als jeder andere Java-Methodenaufruf, dh sie interagieren oder modifizieren sie in keiner Weise. Wenn Sie etwas über Monitore sagen möchten, sollten Sie angeben, dass waitzusätzlich zu den oben genannten Dingen die Sperre für das aufgerufene Objekt vorübergehend aufgehoben wird.
pqnet

Wie funktioniert die Benachrichtigung auf OS Scheduler-Ebene? Ruft notify eine Art Ereignishandler mit einer bestimmten Thread-ID auf, sodass der Scheduler den entsprechenden Thread wieder in die laufende Warteschlange stellen kann? Ich habe noch eine andere Frage, wo passt das Konzept des Spinlocks hin? Wäre es nur für den Schlaf relevant oder verwendet Wait selbst Spinlock auf sehr niedrigem Niveau?
CMCDragonkai

@Erich, Verwenden Sie wait(n)zum Vergleichen mit sleep(n). Es macht keinen Sinn, mit dem No-Arg zu vergleichen.
Pacerier

68

Hier gibt es viele Antworten, aber ich konnte die semantische Unterscheidung nicht finden.

Es geht nicht um den Thread selbst; Beide Methoden sind erforderlich, da sie sehr unterschiedliche Anwendungsfälle unterstützen.

sleep()Sendet den Thread in den Ruhezustand wie zuvor, packt nur den Kontext und stoppt die Ausführung für eine vordefinierte Zeit. Um es also vorzeitig zu aktivieren, müssen Sie die Thread-Referenz kennen. Dies ist in einer Multithread-Umgebung keine häufige Situation. Es wird hauptsächlich für die Zeitsynchronisation (z. B. Aufwachen in genau 3,5 Sekunden) und / oder für hartcodierte Fairness verwendet (schlafen Sie einfach eine Weile und lassen Sie andere Threads arbeiten).

wait()Im Gegenteil, es handelt sich um einen Thread- (oder Nachrichten-) Synchronisationsmechanismus, mit dem Sie einen Thread benachrichtigen können, über den Sie keine Referenz gespeichert haben (und für den Sie sich nicht interessieren). Sie können es sich als Publish-Subscribe-Muster waitvorstellen ( == subscribe undnotify() == Publish). Grundsätzlich senden Sie mit notify () eine Nachricht (die möglicherweise gar nicht empfangen wird und normalerweise egal ist).

Zusammenfassend lässt sich sagen, dass Sie normalerweise sleep()für die wait()Zeitsynchronisation und für die Multithread-Synchronisation verwenden.

Sie könnten auf die gleiche Weise im zugrunde liegenden Betriebssystem oder überhaupt nicht implementiert werden (da frühere Versionen von Java kein echtes Multithreading hatten; wahrscheinlich tun dies auch einige kleine VMs nicht). Vergessen Sie nicht, dass Java auf einer VM ausgeführt wird, sodass Ihr Code je nach VM / OS / HW, auf dem er ausgeführt wird, in etwas anderes umgewandelt wird.


54

Hier habe ich einige wichtige Unterschiede zwischen wait()und sleep()Methoden aufgelistet .
PS: Klicken Sie auch auf die Links, um den Bibliothekscode anzuzeigen (internes Arbeiten, spielen Sie zum besseren Verständnis nur ein wenig herum).

warten()

  1. wait() Methode gibt die Sperre frei.
  2. wait()ist die Methode der ObjectKlasse.
  3. wait() ist die nicht statische Methode - public final void wait() throws InterruptedException { //...}
  4. wait()sollte durch notify()oder notifyAll()Methoden benachrichtigt werden.
  5. wait() Die Methode muss aus einer Schleife aufgerufen werden, um mit Fehlalarmen umgehen zu können.

  6. wait() Die Methode muss aus dem synchronisierten Kontext (dh der synchronisierten Methode oder dem synchronisierten Block) aufgerufen werden, andernfalls wird sie ausgelöst IllegalMonitorStateException

Schlaf()

  1. sleep() Methode gibt die Sperre nicht frei.
  2. sleep()ist die Methode der java.lang.ThreadKlasse.
  3. sleep() ist die statische Methode - public static void sleep(long millis, int nanos) throws InterruptedException { //... }
  4. nach der angegebenen Zeit sleep()ist abgeschlossen.
  5. sleep()Besser nicht aus der Schleife aufrufen ( siehe Code unten ).
  6. sleep()kann von überall angerufen werden. Es gibt keine besonderen Anforderungen.

Ref: Unterschied zwischen Warten und Schlafen

Code-Snippet zum Aufrufen der Wait and Sleep-Methode

synchronized(monitor){
    while(condition == true){ 
        monitor.wait()  //releases monitor lock
    }

    Thread.sleep(100); //puts current thread on Sleep    
}

Thread-Übergang zu verschiedenen Thread-Zuständen


Ist es richtig, dass ein schlafender Thread durch Aufrufe von notify () geweckt werden kann? Einige der anderen Beiträge hier scheinen zu implizieren, dass ein schlafender Thread nicht geweckt, sondern unterbrochen werden kann.
Berimbolo

Ja, Thread.sleep()wird verwendet, um die Prozessorzeit für die anderen Threads verfügbar zu machen. Die Ruhephase kann durch Interrupts (dh durch JVM) beendet werden. Lesen Sie diese stackoverflow.com/questions/4264355/…
Roottraveller

Dieser Beitrag sagt auch, dass Interrupt () das ist, was einen schlafenden Thread weckt? Ich bezog mich auf das von Ihnen veröffentlichte Thread-Statusdiagramm, in dem steht, dass notify oder notifyAll einen schlafenden (nicht wartenden) Thread wieder betriebsbereit macht. Ich möchte nur sicherstellen, dass ich das verstehe.
Berimbolo

@berimbolo notify()oder notifyAll()sind ObjectKlassenmethoden. daher sind sie für alle Klassen verfügbar (dh hier auch für ThreadKlassen). Siehe den Code grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/…
Roottraveller

2
OK Ich muss mehr über die Thread-Planung lesen, da ich keine Beispiele für notify () oder notifyAll () finden kann, die schlafende Threads nur unterbrechen (). Alle Beispiele beziehen sich auf notify () und notifyAll () auf Threads, die auf ein Monitorobjekt warten.
Berimbolo

29

Es gibt einige wichtige Hinweise, die ich nach der Arbeit an Warten und Schlafen abschließe. Schauen Sie sich zuerst das Beispiel mit wait () und sleep () an:

Beispiel 1 : Verwenden von wait () und sleep ():

synchronized(HandObject) {
    while(isHandFree() == false) {
        /* Hand is still busy on happy coding or something else, please wait */
        HandObject.wait();
    }
}

/* Get lock ^^, It is my turn, take a cup beer now */
while (beerIsAvailable() == false) {
    /* Beer is still coming, not available, Hand still hold glass to get beer,
       don't release hand to perform other task */
    Thread.sleep(5000);
}

/* Enjoy my beer now ^^ */
drinkBeers();

/* I have drink enough, now hand can continue with other task: continue coding */
setHandFreeState(true);
synchronized(HandObject) {
    HandObject.notifyAll();
}

Lassen Sie einige wichtige Hinweise klarstellen:

  1. Rufen Sie an :
    • wait (): Ruft den aktuellen Thread auf, der HandObject Object enthält
    • sleep (): Call on Thread Execute Task Get Beer (ist Klassenmethode, wirkt sich also auf den aktuell laufenden Thread aus)
  2. Synchronisiert :
    • wait (): Wenn synchronisierter Multithread auf dasselbe Objekt zugreift (HandObject) (Wenn Kommunikation zwischen mehr als einem Thread erforderlich ist (Thread-Codierung ausführen, Thread ausführen, Bier holen), Zugriff auf dasselbe Objekt HandObject)
    • sleep (): Wenn die Wartebedingung fortgesetzt wird (Warten auf Bier verfügbar)
  3. Festhalten :
    • wait (): Löse die Sperre, damit andere Objekte ausgeführt werden können (HandObject ist kostenlos, du kannst andere Aufgaben erledigen)
    • sleep (): halte die Sperre mindestens t Mal (oder bis zur Unterbrechung) (Mein Job ist immer noch nicht beendet, ich halte die Sperre weiter und warte auf eine Bedingung, um fortzufahren)
  4. Weckzustand :
    • wait (): bis zum Aufruf von notify (), notifyAll () vom Objekt
    • sleep (): bis mindestens die Zeit abläuft oder Interrupt aufruft
  5. Und der letzte Punkt ist die Verwendung, wenn wie estani angibt:

Normalerweise verwenden Sie sleep () für die Zeitsynchronisation und wait () für die Multithread-Synchronisation.

Bitte korrigieren Sie mich, wenn ich falsch liege.


26

Unterschied zwischen wait () und sleep ()

  • Der wesentliche Unterschied besteht darin , dass wait()aus Objectund sleep()ist eine statische Methode Thread.

  • Der Hauptunterschied besteht darin, dass wait()die Sperre sleep()aufgehoben wird, während während des Wartens keine Sperre aufgehoben wird.

  • wait()wird für die Kommunikation zwischen Threads verwendet, während sleep()im Allgemeinen eine Pause bei der Ausführung eingeführt wird.

  • wait()sollte von innen synchronisiert aufgerufen werden oder wir bekommen eine IllegalMonitorStateException, während sleep() kann überall aufgerufen werden.

  • Um einen Thread erneut zu starten wait(), müssen Sie notify()oder aufrufen notifyAll(). Wie für sleep(),den Thread nach einem bestimmten Zeitintervall wird gestartet.

Ähnlichkeiten

  • In beiden Fällen wird der aktuelle Thread in den Status "Nicht ausführbar" versetzt .
  • Beides sind native Methoden.

18

Dies ist eine sehr einfache Frage, da beide Methoden eine völlig unterschiedliche Verwendung haben.

Der Hauptunterschied besteht darin, zu warten, bis die Sperre oder der Monitor freigegeben ist, während der Ruhezustand während des Wartens keine Sperre oder Überwachung aufhebt. Wait wird für die Kommunikation zwischen Threads verwendet, während Sleep verwendet wird, um eine Pause bei der Ausführung einzuführen.

Dies war nur eine klare und grundlegende Erklärung. Wenn Sie mehr wollen, lesen Sie weiter.

Im Falle eines wait()Methoden-Threads befindet er sich im Wartezustand und wird nicht automatisch zurückgegeben, bis die notify()Methode aufgerufen wird (oder notifyAll()wenn sich mehr als ein Thread im Wartezustand befindet und Sie alle diese Threads aktivieren möchten). Und Sie benötigen eine synchronisierte Sperre oder Objektsperre oder Klassensperre, um auf die Methoden wait()oder notify()oder zugreifen zu notifyAll()können. Und noch etwas, daswait() Methode wird für die Kommunikation zwischen Threads verwendet, da Sie einen anderen Thread benötigen, um diesen Thread zu aktivieren, wenn sich ein Thread im Wartezustand befindet.

In diesem Fall sleep()handelt es sich jedoch um eine Methode, mit der der Vorgang einige Sekunden oder die gewünschte Zeit gehalten wird. Weil Sie keine notify()oder keine notifyAll()Methode provozieren müssen , um diesen Thread zurückzubekommen. Oder Sie benötigen keinen anderen Thread, um diesen Thread zurückzurufen. Wenn Sie möchten, dass nach wenigen Sekunden etwas passiert, wie in einem Spiel nach dem Zug des Benutzers, möchten Sie, dass der Benutzer wartet, bis der Computer spielt, dann können Sie das erwähnensleep() Methode .

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

Dies sind alle Unterschiede zwischen sleep()undwait() .

Und es gibt eine Ähnlichkeit zwischen beiden Methoden: Beide sind geprüfte Anweisungen, daher müssen Sie catch oder throw versuchen, um auf diese Methoden zuzugreifen.

Ich hoffe, dies wird dir helfen.


16

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

Thread.sleep()Sendet den aktuellen Thread für einige Zeit in den Status "Nicht ausführbar" . Der Thread behält die Monitore bei, die er erworben hat - dh wenn sich der Thread derzeit in einem synchronisierten Block oder einer synchronisierten Methode befindet, kann kein anderer Thread in diesen Block oder diese Methode eintreten. Wenn ein anderer Thread aufruft t.interrupt(), wird der schlafende Thread aufgeweckt.

Beachten Sie, dass der Schlaf eine statische Methode ist, was bedeutet, dass er immer den aktuellen Thread betrifft (den, der die Schlafmethode ausführt). Ein häufiger Fehler besteht darin, aufzurufen, t.sleep()wo t ein anderer Thread ist. Selbst dann ist es der aktuelle Thread, der in den Ruhezustand wechselt, nicht der t-Thread.

t.suspend()ist veraltet. Mit dieser Option kann ein anderer Thread als der aktuelle Thread angehalten werden. Ein angehaltener Thread behält alle seine Monitore und da dieser Zustand nicht unterbrechbar ist, ist er anfällig für Deadlocks.

object.wait()sendet den aktuellen Thread in den „Nicht Runnable“ Zustand, wie sleep(), aber mit einer Torsion. Wait wird für ein Objekt aufgerufen, nicht für einen Thread. Wir nennen dieses Objekt das "Sperrobjekt". Bevor lock.wait()aufgerufen wird, muss der aktuelle Thread mit dem Sperrobjekt synchronisiert werden. wait() Löst dann diese Sperre auf und fügt den Thread zur "Warteliste" hinzu, die der Sperre zugeordnet ist. Später kann ein anderer Thread mit demselben Sperrobjekt synchronisieren und aufrufen lock.notify(). Dies weckt den ursprünglichen, wartenden Thread. Grundsätzlich ist wait()/ notify()wie sleep()/ interrupt(), nur der aktive Thread benötigt keinen direkten Zeiger auf den schlafenden Thread, sondern nur auf das gemeinsam genutzte Sperrobjekt.


14

Warten und Schlafen sind zwei verschiedene Dinge:

  • Im sleep() Thread funktioniert für die angegebene Dauer nicht mehr.
  • Im wait()Thread funktioniert es nicht mehr, bis das Objekt, auf das gewartet wird, im Allgemeinen von anderen Threads benachrichtigt wird.

Sie können jedoch einen schlafenden Thread unterbrechen. In diesem Fall ist wait () redundant, da es auch CPU-Zyklen verschwendet :-(
Geek

9
Warten verschwendet keine CPU-Zyklen.
Peter Štibraný

1
@ Peter - ich denke schon. Es wartet () auf seinen Teil der CPU-Zyklen und dann gibt das Betriebssystem die CPU-Zyklen an andere Threads weiter. Ich denke, dies könnte vom Betriebssystem abhängig sein, ich bin mir nicht sicher.
Geek

3
Es wäre eine sehr schlechte Implementierung von wait (), wenn CPU-Zyklen verschwendet würden. wait / notify wird häufig für die Kommunikation zwischen Threads verwendet.
Peter Štibraný

2
@ Pacerier Die beiden Konstrukte sind für einen anderen Zweck bestimmt. Wenn Sie möchten, dass ein Thread für eine festgelegte Zeitspanne angehalten wird sleep, wenn Sie möchten, dass er angehalten wird, bis eine Eingabe von der anderen stammt, verwenden Sie wait/ notify. interruptsoll einem Thread signalisieren, dass er aufhören soll, was er tut, und beenden soll. Es wird von E / A-Funktionen behandelt sleep, waitblockiert diese aber auch (und Sie können Funktionen mit demselben Verhalten implementieren, indem Sie die Methode aufrufen Thread.interrupted()). In Bezug auf die Leistung werden Funktionen normalerweise für das Ziel optimiert, für das sie entworfen wurden.
pqnet

11

sleepist eine Methode von Thread, waitist eine Methode von Object, wait/notifyist also eine Technik zum Synchronisieren gemeinsam genutzter Daten in Java (mithilfe von Monitor ), sleepist jedoch eine einfache Methode des Threads, um sich selbst anzuhalten.


8

sleep () ist eine Methode, die verwendet wird, um den Prozess für einige Sekunden oder die gewünschte Zeit anzuhalten. Im Falle von wait () befindet sich der Methodenthread im Wartezustand und wird nicht automatisch zurückgegeben, bis wir notify () oder aufrufen notifyAll ().

Der Hauptunterschied besteht darin, dass wait () die Sperre oder den Monitor aufhebt, während sleep () während des Wartens keine Sperre oder keinen Monitor aufhebt. Wait wird für die Kommunikation zwischen Threads verwendet, während Sleep verwendet wird, um im Allgemeinen eine Pause bei der Ausführung einzuführen.

Thread.sleep () versetzt den aktuellen Thread für einige Zeit in den Status "Nicht ausführbar". Der Thread behält die von ihm erfassten Monitore bei. Wenn sich der Thread derzeit in einem synchronisierten Block oder einer synchronisierten Methode befindet, kann kein anderer Thread in diesen Block oder diese Methode eintreten. Wenn ein anderer Thread t.interrupt () aufruft, wird der schlafende Thread aktiviert. Beachten Sie, dass der Ruhezustand eine statische Methode ist. Dies bedeutet, dass er immer den aktuellen Thread betrifft (den, der die Schlafmethode 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 in den Ruhezustand wechselt, nicht der t-Thread.

object.wait () versetzt den aktuellen Thread wie sleep () in den Status "Nicht ausführbar", jedoch mit einer Wendung. Wait wird für ein Objekt aufgerufen, nicht für einen Thread. Wir nennen dieses Objekt das "Sperrobjekt". Bevor lock.wait () aufgerufen wird, muss der aktuelle Thread für das Sperrobjekt synchronisiert werden. wait () gibt dann diese Sperre frei und fügt den Thread zur Warteliste hinzu, die der Sperre zugeordnet ist. Später kann ein anderer Thread mit demselben Sperrobjekt synchronisieren und lock.notify () aufrufen. Dies weckt den ursprünglichen, wartenden Thread. Grundsätzlich ist wait () / notify () wie sleep () / interrupt (), nur der aktive Thread benötigt keinen direkten Zeiger auf den schlafenden Thread, sondern nur auf das gemeinsam genutzte Sperrobjekt.

synchronized(LOCK) {   
   Thread.sleep(1000); // LOCK is held
}

synchronized(LOCK) {   
   LOCK.wait(); // LOCK is not held
}

Lassen Sie uns alle oben genannten Punkte kategorisieren:

Call on:

  • wait (): Ruft ein Objekt auf; Der aktuelle Thread muss mit dem Sperrobjekt synchronisiert werden.
  • sleep (): Rufe einen Thread auf; Immer aktuell ausgeführter Thread.

Synchronized:

  • wait (): Wenn mehrere Threads synchronisiert sind, greifen sie nacheinander auf dasselbe Objekt zu.
  • sleep (): Wenn mehrere Threads synchronisiert sind, warten Sie auf den Ruhezustand des schlafenden Threads.

Hold lock:

  • wait (): Lösen Sie die Sperre, damit andere Objekte ausgeführt werden können.
  • sleep (): Halten Sie die Sperre mindestens t Mal, wenn eine Zeitüberschreitung angegeben ist oder jemand unterbricht.

Wake-up condition:

  • wait (): bis zum Aufruf von notify (), notifyAll () vom Objekt
  • sleep (): bis mindestens die Zeit abgelaufen ist oder Interrupt () aufgerufen wurde.

Usage:

  • sleep (): zur Zeitsynchronisation und;
  • wait (): für die Multithread-Synchronisation.

Ref: diff sleepundwait


6

In einfachen Worten, warten ist warten, bis ein anderer Thread Sie aufruft, während sleep für einen bestimmten Zeitraum "nächste Anweisung nicht ausführen" lautet.

Darüber hinaus ist sleep eine statische Methode in der Thread-Klasse und arbeitet mit Thread, während wait () in der Object-Klasse ist und für ein Objekt aufgerufen wird.

Ein weiterer Punkt, wenn Sie wait für ein Objekt aufrufen, synchronisiert der betreffende Thread das Objekt und wartet dann. :) :)


1
Warum brauchst du beides? Warum reicht sleep () nicht aus?
Geek

2
Notify wird für die Kommunikation zwischen Threads verwendet. Um wait aufzurufen, benötigen Sie ein Objekt, synchronisieren es und rufen dann wait auf. Um benachrichtigt zu werden, benötigen Sie einen anderen Thread, um mit demselben Objekt zu synchronisieren und notify aufzurufen.
Peter Štibraný

6

waitund sleepMethoden sind sehr unterschiedlich:

  • sleep hat keine Möglichkeit "aufzuwachen",
  • wohingegen waites eine Möglichkeit gibt, während der Wartezeit "aufzuwachen", indem ein anderer Thread notifyoder aufruft notifyAll.

Kommen Sie, um darüber nachzudenken, die Namen sind in dieser Hinsicht verwirrend; ist jedoch sleepein Standardname und entspricht waitdem WaitForSingleObjectoder WaitForMultipleObjectsin der Win-API.


3
Aber wir können einen Schlaf unterbrechen, nicht wahr? Was ist der Unterschied zwischen Schlaf / Interrupt und Warten / Benachrichtigen?
Pacerier

2
Sie können eine schlafende Person unterbrechen, aber nur eine wartende Person benachrichtigen. Threads sind die gleichen.
Rishi

5

Aus diesem Beitrag: http://javaconceptoftheday.com/difference-between-wait-and-sleep-methods-in-java/

wait () Methode.

1) Der Thread, der die wait () -Methode aufruft, gibt die darin enthaltene Sperre frei.

2) Der Thread gewinnt die Sperre zurück, nachdem andere Threads entweder die Methoden notify () oder notifyAll () für dieselbe Sperre aufgerufen haben.

3) Die wait () -Methode muss innerhalb des synchronisierten Blocks aufgerufen werden.

4) Die wait () -Methode wird immer für Objekte aufgerufen.

5) Wartende Threads können von anderen Threads durch Aufrufen der Methoden notify () oder notifyAll () aktiviert werden.

6) Um die wait () -Methode aufzurufen, muss der Thread über eine Objektsperre verfügen.

sleep () Methode

1) Der Thread, der die sleep () -Methode aufruft, gibt die darin enthaltene Sperre nicht frei.

2) Die sleep () -Methode kann innerhalb oder außerhalb des synchronisierten Blocks aufgerufen werden.

3) Die sleep () -Methode wird immer für Threads aufgerufen.

4) Schlafende Threads können nicht von anderen Threads geweckt werden. In diesem Fall löst der Thread eine InterruptedException aus.

5) Um die sleep () -Methode aufzurufen, muss der Thread keine Objektsperre haben.


4

Hier befindet sich wait () im Wartezustand, bis es von einem anderen Thread benachrichtigt wird, aber wo sleep () einige Zeit haben wird. Danach wird es automatisch in den Bereitschaftszustand versetzt ...


4
  1. wait()ist eine Methode der ObjectKlasse.
    sleep()ist eine Methode der ThreadKlasse.

  2. sleep()Ermöglicht dem Thread, sleepfür x Millisekunden in den Status zu wechseln.
    Wenn ein Thread in den Ruhezustand wechselt it doesn’t release the lock.

  3. wait()ermöglicht dem Thread, die Sperre zu lösen und goes to suspended state.
    Dieser Thread ist aktiv, wenn eine notify()oder notifAll()-Methode für dasselbe Objekt aufgerufen wird.


4

Ein möglicher großer Unterschied zwischen Schlaf / Interrupt und Warten / Benachrichtigen ist der folgende

Das Generieren einer Ausnahme, wenn sie nicht benötigt wird, ist ineffizient. Wenn Sie Threads haben, die mit einer hohen Rate miteinander kommunizieren, würde dies viele Ausnahmen erzeugen, wenn Sie die ganze Zeit Interrupt aufrufen, was eine totale Verschwendung von CPU darstellt.


+1, Ein gültiger Punkt, obwohl das Streiten über die Interna von Implementierungen für die Leistungsanalyse relevanter sein kann ...
Pacerier

Mit anderen Worten, der Aufwand für das Erstellen von Ausnahmen kann erheblich geringer sein als der Aufwand für die Implementierung des einen gegenüber dem anderen System.
Pacerier

3

Sie haben Recht - Sleep () bewirkt, dass dieser Thread "in den Ruhezustand versetzt" wird und die CPU ausgeht und andere Threads (auch als Kontextwechsel bezeichnet) verarbeitet, wobei Wait meiner Meinung nach die CPU dazu bringt, den aktuellen Thread zu verarbeiten.

Wir haben beides, denn obwohl es sinnvoll erscheint, andere Benutzer die CPU verwenden zu lassen, während Sie sie nicht verwenden, ist das Umschalten des Kontexts tatsächlich mit einem Overhead verbunden - je nachdem, wie lange der Ruhezustand dauert, kann dies in CPU-Zyklen teurer sein Threads zu wechseln, als es ist, einfach Ihren Thread für ein paar ms nichts tun zu lassen.

Beachten Sie auch, dass der Schlaf einen Kontextwechsel erzwingt.

Außerdem kann das Betriebssystem während der Wartezeit (im Allgemeinen ist es nicht möglich, die Kontextumschaltung zu steuern) andere Threads verarbeiten (und wird dies auch für längere Wartezeiten tun).


4
wait () hält die CPU nicht davon ab, den aktuellen Thread zu verarbeiten. Es ist wie Schlaf, da es auch einen Kontextwechsel verursacht: javamex.com/tutorials/threads/context_switch.shtml . Ich habe um ein halbes Jahr rund um den Stackoverflow gebeten und es scheint, dass niemand weiß, was der Unterschied zwischen Warten / Benachrichtigen und Schlafen / Unterbrechen ist.
Pacerier

Obwohl der Ruhezustand die CPU nicht bei der Verarbeitung des aktuellen Threads hält, ist dies meiner Meinung nach eine kleine Belastung für die CPU, da die CPU den Zeitpunkt verfolgen muss, zu dem der Ruhezustand beendet werden soll. Dieser externe Trigger wie "Benachrichtigen" wartet nicht. Nein?
Vladimir Nabokov

@VladimirNabokov, Der externe Auslöser ist interrupt. Die Endzeit ist nin wait(n). ¶¶ Es ist jetzt 8 Jahre her und immer noch hat niemand die Antwort!
Pacerier

3

Die Methoden werden für verschiedene Dinge verwendet.

Thread.sleep(5000);   // Wait until the time has passed.

Object.wait();        // Wait until some other thread tells me to wake up.

Thread.sleep (n) kann unterbrochen werden, Object.wait () muss jedoch benachrichtigt werden. Es ist möglich, die maximale Wartezeit anzugeben: Object.wait(5000)Es wäre also möglich, dies zu verwenden wait, ähm, sleepaber dann müssen Sie sich um Sperren kümmern.

Keine der Methoden verwendet die CPU im Schlaf / Warten.

Die Methoden werden unter Verwendung von nativem Code implementiert, wobei ähnliche Konstrukte verwendet werden, jedoch nicht auf dieselbe Weise.

Überzeugen Sie sich selbst: Ist der Quellcode nativer Methoden verfügbar? Die Datei /src/share/vm/prims/jvm.cppist der Ausgangspunkt ...


Das Timing von Thread.sleep kann auch auf unbestimmt eingestellt werden. Das Timing von Object.wait kann auch auf definit gesetzt werden. Diese Antwort erklärt nicht, warum wir zwei Hämmer brauchen, die dasselbe tun.
Pacerier

Thread.sleep(big_num) muss unterbrochen werden. Object.wait(small_num) kann benachrichtigt werden.
Pacerier

3

Warten () und schlafen () Unterschiede?

Thread.sleep () Sobald seine Arbeit abgeschlossen ist, wird nur die Sperre für alle freigegeben. bis es niemals das Schloss für irgendjemanden freigibt.

  Sleep() take the key, its never release the key to anyone, when its work completed then only its release then only take the key waiting stage threads.

Object.wait () Wenn es in die Wartephase geht, gibt es den Schlüssel frei und wartet basierend auf dem Parameter einige Sekunden.

Zum Beispiel:

Wenn Sie den Kaffee in Ihre rechte Hand nehmen, können Sie einen anderen von derselben Hand nehmen. Wann wird Ihr Ablegen dann nur ein anderes Objekt des gleichen Typs hier nehmen? ebenfalls. das ist sleep () du schläfst du hast keine arbeit gemacht, du schläfst nur .. das gleiche auch hier.

warten(). Wenn Sie niedergeschlagen sind und einen anderen nehmen, während Sie warten, ist das Warten

Sie spielen einen Film oder etwas in Ihrem System ab, genauso wie ein Player, den Sie nicht mehr als einen gleichzeitig abspielen können. Das ist hier, wenn Sie einen anderen Film oder Song schließen und auswählen, während Sie warten


3

waitgibt die Sperre frei und sleeptut es nicht. Ein Thread sich in Wartestellung ist , die für das Aufwachen, sobald notifyoder notifyAllgenannt wird. Aber im Falle, dass sleepder Thread die Sperre behält und er erst dann berechtigt ist, wenn die Ruhezeit abgelaufen ist.


Also, wenn der Thread 10 Sekunden lang schläft und eine unterbrochene Ausnahme auftritt ????
Geek

@Geek An InterruptedExceptionwird geworfen, so wie es im Javadoc steht.
Marquis von Lorne

@EJP: Sind Sie derselbe EJP, der in den sun.java.com-Foren war? Zumindest schlägt Ihre Punktzahl dasselbe vor :-)
Geek

2

sleep()Die Methode bewirkt, dass der aktuelle Thread für eine bestimmte Zeit vom laufenden Status in den Blockstatus wechselt. Wenn der aktuelle Thread die Sperre eines Objekts hat, hält er diese weiterhin, was bedeutet, dass andere Threads keine synchronisierte Methode in diesem Klassenobjekt ausführen können.

wait() Die Methode bewirkt, dass der aktuelle Thread entweder für eine bestimmte Zeit oder bis zur Benachrichtigung in den Blockstatus wechselt. In diesem Fall gibt der Thread jedoch die Sperre des Objekts frei (was bedeutet, dass andere Threads alle synchronisierten Methoden des aufrufenden Objekts ausführen können.


2

Meiner Meinung nach besteht der Hauptunterschied zwischen beiden Mechanismen darin, dass Sleep / Interrupt die grundlegendste Art des Umgangs mit Threads ist, während Wait / Notify eine Abstraktion ist, die darauf abzielt, die Kommunikation zwischen Threads zu vereinfachen. Dies bedeutet, dass Schlaf / Interrupt alles kann, aber dass diese spezielle Aufgabe schwieriger zu erledigen ist.

Warum ist Warten / Benachrichtigen besser geeignet? Hier einige persönliche Überlegungen:

  1. Es erzwingt die Zentralisierung. Es ermöglicht die Koordination der Kommunikation zwischen einer Gruppe von Threads mit einem einzelnen gemeinsam genutzten Objekt. Dies vereinfacht die Arbeit erheblich.

  2. Es erzwingt die Synchronisation. Weil der Programmierer den Aufruf zum Warten / Benachrichtigen in einen synchronisierten Block einschließt.

  3. Es ist unabhängig von der Herkunft und Anzahl der Threads. Mit diesem Ansatz können Sie beliebig mehr Threads hinzufügen, ohne die anderen Threads zu bearbeiten oder die vorhandenen zu verfolgen. Wenn Sie Sleep / Interrupt verwendet haben, müssen Sie zuerst die Verweise auf die Sleeping-Threads beibehalten und sie dann einzeln von Hand unterbrechen.

Ein Beispiel aus dem wirklichen Leben, das gut erklärt werden kann, ist ein klassisches Restaurant und die Methode, mit der das Personal untereinander kommuniziert: Die Kellner lassen die Kundenanfragen an einem zentralen Ort (einer Korkplatte, einem Tisch usw.). klingeln, und die Arbeiter aus der Küche kommen, um solche Anfragen entgegenzunehmen. Sobald ein Kurs fertig ist, klingelt das Küchenpersonal erneut, damit die Kellner es bemerken und zu den Kunden bringen.


2

Ein Beispiel für den Schlaf löst die Sperre nicht und das Warten nicht

Hier gibt es zwei Klassen:

  1. Main : Enthält die Hauptmethode und zwei Threads.
  2. Singleton : Dies ist eine Singleton-Klasse mit zwei statischen Methoden, getInstance () und getInstance (boolean isWait).

    public class Main {
    
    private static Singleton singletonA = null;
    private static Singleton singletonB = null;
    
    public static void main(String[] args) throws InterruptedException {
    
    Thread threadA = new Thread() {
        @Override
        public void run() {
    
            singletonA = Singleton.getInstance(true);
    
        }
    };
    
    Thread threadB = new Thread() {
        @Override
        public void run() {
            singletonB = Singleton.getInstance();
    
            while (singletonA == null) {
                System.out.println("SingletonA still null");
            }
    
            if (singletonA == singletonB) {
                System.out.println("Both singleton are same");
            } else {
                System.out.println("Both singleton are not same");
            }
    
        }
    };
    
    threadA.start();
    threadB.start();
    
     }
    }

und

public class Singleton {

    private static Singleton _instance;

    public static Singleton getInstance() {

    if (_instance == null) {
        synchronized (Singleton.class) {
            if (_instance == null)
                _instance = new Singleton();
        }
    }
    return _instance;

}

public static Singleton getInstance(boolean isWait) {

    if (_instance == null) {
        synchronized (Singleton.class) {
            if (_instance == null) {
                if (isWait) {
                    try {
                        // Singleton.class.wait(500);//Using wait
                        Thread.sleep(500);// Using Sleep
                        System.out.println("_instance :"
                                + String.valueOf(_instance));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                _instance = new Singleton();
            }
        }
    }
    return _instance;

 }
}

Führen Sie nun dieses Beispiel aus, um die folgende Ausgabe zu erhalten:

_instance :null
Both singleton are same

Hier sind Singleton-Instanzen, die von threadA und threadB erstellt wurden, identisch. Dies bedeutet, dass ThreadB draußen wartet, bis ThreadA seine Sperre aufhebt.

Ändern Sie nun die Datei Singleton.java, indem Sie Thread.sleep (500) kommentieren. Methode und Kommentieren von Singleton.class.wait (500); . Hier wegen Singleton.class.wait (500); Die Methode threadA gibt alle Erfassungssperren frei und wechselt in den Status "Nicht ausführbar". ThreadB erhält eine Änderung, um in den synchronisierten Block einzutreten.

Jetzt nochmal laufen lassen:

SingletonA still null
SingletonA still null
SingletonA still null
_instance :com.omt.sleepwait.Singleton@10c042ab
SingletonA still null
SingletonA still null
SingletonA still null
Both singleton are not same

Hier sind von threadA und threadB erstellte Singleton-Instanzen NICHT identisch, da threadB geändert wurde, um in den synchronisierten Block einzutreten. Nach 500 Millisekunden startete threadA von seiner letzten Position und erstellte ein weiteres Singleton-Objekt.


2

Sollte vom synchronisierten Block aufgerufen werden: Die wait() Methode wird immer vom synchronisierten Block aufgerufen, dh die wait()Methode muss den Objektmonitor vor dem Objekt sperren, für das sie aufgerufen wird. Die sleep()Methode kann jedoch von außerhalb des synchronisierten Blocks aufgerufen werden, d. H.sleep() Methode benötigt keinen Objektmonitor.

IllegalMonitorStateException: Wenn die wait()Methode aufgerufen wird, ohne eine Objektsperre zu erhalten, IllegalMonitorStateExceptionwird sie zur Laufzeit ausgelöst, die sleep()Methode löst jedoch niemals eine solche Ausnahme aus.

Gehört zu welcher Klasse: wait() Methode gehört zur java.lang.ObjectKlasse, aber sleep()Methode gehört zur java.lang.ThreadKlasse.

Wird für Objekt oder Thread aufgerufen: Die wait() Methode wird für Objekte aufgerufen, aber die sleep()Methode wird für Threads und nicht für Objekte aufgerufen.

Thread-Status: wenn wait()Methode auf dem Objekt aufgerufen wird, Thread, holded Objekts des Monitors geht vom Laufen zu Wartebetrieb und kann zu runnable Zustand zurück , nur wenn notify()oder notifyAll()Methode für das Objekt aufgerufen wird. Und später plant der Thread-Scheduler, dass dieser Thread vom ausführbaren zum laufenden Status wechselt. Wenn ein sleep()Thread aufgerufen wird, wechselt er vom laufenden in den wartenden Zustand und kann nach Ablauf der Ruhezeit in den ausführbaren Zustand zurückkehren.

Beim Aufruf aus dem synchronisierten Block: Wenn die wait()Methode aufgerufen wird, verlässt der Thread die Objektsperre. Aber sleep()Verfahren , wenn von synchronisierten Block oder Methode Thread aufgerufen nicht Blätter Sperrobjekt.

Weitere Informationen


wahrscheinlich eine bessere Referenz-URL als diese.
Drew

2

Von der Oracle-Dokumentationsseite auf wait () Methode von Object:

public final void wait()
  1. Bewirkt, dass der aktuelle Thread wartet, bis ein anderer Thread die notify()Methode oder die notifyAll()Methode für dieses Objekt aufruft . Mit anderen Worten, diese Methode verhält sich genau so, als würde sie den Aufruf einfach ausführen wait(0).
  2. Der aktuelle Thread muss den Monitor dieses Objekts besitzen. Der Thread gibt den Besitz dieses Monitors frei und wartet, bis ein anderer Thread die auf dem Monitor dieses Objekts wartenden Threads benachrichtigt, um aufzuwachen
  3. Interrupts und falsche Aufweckvorgänge sind möglich
  4. Diese Methode sollte nur von einem Thread aufgerufen werden, der Eigentümer des Monitors dieses Objekts ist

Diese Methode wirft

  1. IllegalMonitorStateException - Wenn der aktuelle Thread nicht der Eigentümer des Objektmonitors ist.

  2. InterruptedException- Wenn ein Thread den aktuellen Thread unterbrochen hat, bevor oder während der aktuelle Thread auf eine Benachrichtigung wartete. Der unterbrochene Status des aktuellen Threads wird gelöscht, wenn diese Ausnahme ausgelöst wird.

Von der Oracle-Dokumentationsseite zur sleep () -Methode der ThreadKlasse:

public static void sleep(long millis)
  1. Bewirkt, dass der aktuell ausgeführte Thread für die angegebene Anzahl von Millisekunden in den Ruhezustand versetzt wird (die Ausführung wird vorübergehend eingestellt), abhängig von der Genauigkeit und Genauigkeit der Systemzeitgeber und -planer.
  2. Der Thread verliert nicht den Besitz von Monitoren.

Diese Methode wirft:

  1. IllegalArgumentException - wenn der Wert von Millis negativ ist

  2. InterruptedException- Wenn ein Thread den aktuellen Thread unterbrochen hat. Der unterbrochene Status des aktuellen Threads wird gelöscht, wenn diese Ausnahme ausgelöst wird.

Anderer Hauptunterschied:

wait()ist eine nicht statische Methode (Instanzmethode) im Gegensatz zur statischen Methode sleep()(Klassenmethode).


1

wait()ist innerhalb einer synchronisierten Methode gegeben , während sleep()in einem nicht synchronisierten Verfahren gegeben, weil wait()Methode für das Objekt die Sperre freizugeben , sondern sleep()oder yield()des entbindet lock().


sleep()kann sich innerhalb eines synchronizedBlocks oder einer Methode befinden. Antwort erklärt nichts.
Marquis von Lorne

1
  • Die Methode wait(1000)bewirkt , dass der aktuelle Thread bis zu einer Sekunde in den Ruhezustand wechselt .
    • Ein Thread kann weniger als 1 Sekunde schlafen, wenn er den Methodenaufruf notify()odernotifyAll() empfängt .
  • Der Aufruf von sleep(1000)bewirkt , dass der aktuelle Thread genau 1 Sekunde lang in den Ruhezustand wechselt .
    • Ebenfalls schlafende Thread hält keine Ressource gesperrt . Aber wartender Thread tut es.

1
sleep(1000)garantiert nicht, genau 1 Sekunde zu schlafen. Es kann vorher unterbrochen werden.
Lucio

1
Diese Beiträge sind so verwirrend. Alle anderen Beiträge in diesem Thread besagen, dass ein schlafender Thread das Schloss hält und dass ein wartender Thread das Schloss NICHT hält. In ähnlicher Weise impliziert der Beitrag mit dem Diagramm, dass Aufrufe zum Benachrichtigen () Wake-Sleeping-Threads aktivieren, andere Beiträge (und Thread-Statusdiagramme) jedoch implizieren, dass nur Interrupt () oder die verstrichene Zeitüberschreitung dies tun. Ich habe mir gerade eine Kopie von Java Concurrency in der Praxis bestellt, etwas, das ich schon vor langer Zeit hätte lesen sollen!
Berimbolo

1

Eigentlich ist das alles in Java-Dokumenten klar beschrieben (aber das habe ich erst nach dem Lesen der Antworten erkannt).

http://docs.oracle.com/javase/8/docs/api/index.html :

wait () - Der aktuelle Thread muss den Monitor dieses Objekts besitzen. Der Thread gibt den Besitz dieses Monitors frei und wartet, bis ein anderer Thread Threads benachrichtigt, die auf dem Monitor dieses Objekts warten, um entweder durch einen Aufruf der notify-Methode oder der notifyAll-Methode aufzuwecken. Der Thread wartet dann, bis er wieder Eigentümer des Monitors werden kann und die Ausführung fortsetzt.

sleep () - Bewirkt, dass der aktuell ausgeführte Thread für die angegebene Anzahl von Millisekunden in den Ruhezustand versetzt wird (die Ausführung wird vorübergehend eingestellt), abhängig von der Genauigkeit und Genauigkeit der Systemzeitgeber und -planer. Der Thread verliert nicht den Besitz von Monitoren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.