Question Différence entre wait () et sleep ()


Quelle est la différence entre un wait() et sleep() dans les threads?

Est-ce que je comprends qu'un wait()-ing Thread est toujours en mode de fonctionnement et utilise des cycles de processeur, mais un sleep()-ing ne consomme aucun cycle de CPU correct?

Pourquoi avons-nous tous les deux  wait() et sleep(): comment leur mise en œuvre varie-t-elle à un niveau inférieur?


1026
2018-06-24 06:48


origine


Réponses:


UNE wait peut être "réveillé" par un autre fil appelant notify sur le moniteur qui est en attente tandis qu'un sleep ne peux pas. Aussi un wait (et notify) doit se produire dans un bloc synchronized sur l'objet moniteur alors que sleep ne fait pas:

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

À ce stade, le thread en cours d'exécution attend et libère le moniteur. Un autre thread peut faire

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

(Sur le même mon objet) et le premier thread (en supposant que c'est le seul thread qui attend sur le moniteur) va se réveiller.

Vous pouvez également appeler notifyAll si plus d'un thread attend sur le moniteur - cela va se réveiller tous en haut. Cependant, un seul des threads sera en mesure de saisir le moniteur (rappelez-vous que le wait est dans un synchronized bloquer) et continuer - les autres seront alors bloqués jusqu'à ce qu'ils puissent acquérir le verrou du moniteur.

Un autre point est que vous appelez wait sur Object lui-même (c'est-à-dire que vous attendez sur le moniteur d'un objet) alors que vous appelez sleep sur Thread.

Encore un autre point est que vous pouvez obtenir wakeups parasite de wait (c'est-à-dire que le fil qui attend reprend sans raison apparente). Vous devriez toujours wait en tournant sur une condition comme suit:

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

739
2018-06-24 06:50



Une différence clé non encore mentionnée est que pendant que vous dormez ne pas libère les verrous qu'il contient, tandis que l'attente libère le verrou sur l'objet wait() est appelé.

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


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

285
2018-06-24 07:06



j'ai trouvé ce lien utile (quelles références ce post). Cela fait la différence entre sleep(), wait(), et yield() en termes humains. (au cas où les liens disparaissent, j'ai inclus le post ci-dessous avec un balisage supplémentaire)

Tout finit par arriver à l'ordonnanceur du système d'exploitation, qui   distribue les délais aux processus et aux threads.

sleep(n) dit "J'en ai fini avec mon temps, et s'il vous plait, ne me donnez pas   un autre pendant au moins n millisecondes. " L'OS n'essaie même pas de   planifier le fil de couchage jusqu'à ce que le temps demandé soit écoulé.

yield() dit "J'en ai fini avec mon temps, mais j'ai encore du travail à faire   faire." L'OS est libre de donner immédiatement au thread un autre timeslice,   ou pour donner un autre fil ou traiter le processeur le fil de rendement   juste abandonné.

.wait() dit "J'en ai fini avec mon temps. Ne me donne pas d'autre   timeslice jusqu'à ce que quelqu'un appelle notify (). " Comme avec sleep(), l'OS ne sera pas   même essayer de planifier votre tâche à moins que quelqu'un appelle notify() (ou l'un des   quelques autres scénarios de réveil se produisent).

Les threads perdent également le reste de leur temps lorsqu'ils effectuent   blocage IO et dans quelques autres circonstances. Si un fil fonctionne   à travers le temps entier, le système d'exploitation prend le contrôle à peu près comme   si yield()avait été appelé, afin que d'autres processus puissent s'exécuter.

Vous avez rarement besoin yield(), mais si vous avez une application de calcul lourde avec   limites de tâches logiques, en insérant un yield()  pourrait améliorer le système   la réactivité (au détriment du temps - les changements de contexte, même juste   à l'OS et retour, ne sont pas libres). Mesurez et testez les objectifs que vous avez   se soucient de, comme toujours.


198
2017-08-05 19:32



Il y a beaucoup de réponses ici mais je n'ai pas pu trouver la distinction sémantique mentionnée.

Ce n'est pas à propos du fil lui-même; les deux méthodes sont nécessaires car elles prennent en charge des cas d'utilisation très différents.

sleep() envoie le Thread pour dormir comme avant, il empaquette juste le contexte et arrête l'exécution pendant un temps prédéfini. Donc, afin de le réveiller avant l'heure prévue, vous devez connaître la référence Thread. Ce n'est pas une situation courante dans un environnement multithread. Il est principalement utilisé pour la synchronisation temporelle (par exemple, le réveil en exactement 3,5 secondes) et / ou l'équité codée en dur (il suffit de dormir pendant un moment et de laisser les autres threads fonctionner).

wait(), au contraire, est un mécanisme de synchronisation de thread (ou de message) qui vous permet de notifier un Thread dont vous n'avez pas de référence stockée (ni care). Vous pouvez le considérer comme un modèle de publication-abonnement (wait == abonnez-vous et notify() == publier). Fondamentalement, en utilisant notify (), vous envoyez un message (qui peut même ne pas être reçu du tout et normalement vous vous en fichez).

Pour résumer, vous utilisez normalement sleep() pour la synchronisation du temps et wait() pour la synchronisation multi-thread.

Ils pourraient être implémentés de la même manière dans le système d'exploitation sous-jacent, ou pas du tout (comme les versions précédentes de Java n'avaient pas vraiment de multithreading, probablement certaines petites machines virtuelles ne le font pas non plus). N'oubliez pas que Java s'exécute sur une machine virtuelle, de sorte que votre code sera transformé en quelque chose de différent selon le VM / OS / HW sur lequel il est exécuté.


64
2018-04-19 10:38



Ici, j'ai énuméré quelques différences importantes entre wait() et sleep() méthodes
PS:  Cliquez également sur les liens pour voir le code de la bibliothèque (fonctionnement interne, il suffit de jouer un peu pour une meilleure compréhension). 

attendez()

  1. wait() méthode libère le verrou.
  2. wait() est la méthode de Object classe.
  3. wait() est la méthode non statique - public final void wait() throws InterruptedException { //...}
  4. wait() devrait être notifié par notify() ou notifyAll() méthodes
  5. wait() la méthode doit être appelée à partir d'une boucle afin de gérer les fausses alarmes.

  6. wait() La méthode doit être appelée à partir du contexte synchronisé (c'est-à-dire la méthode ou le bloc synchronisé), sinon elle jettera IllegalMonitorStateException

dormir()

  1. sleep() méthode ne libère pas le verrou.
  2. sleep() est la méthode de java.lang.Thread classe.
  3. sleep() est la méthode statique - public static void sleep(long millis, int nanos) throws InterruptedException { //... }
  4. après le laps de temps spécifié, sleep() est terminé.
  5. sleep() préférable de ne pas appeler à partir d'une boucle (c'est-à-dire voir le code ci-dessous).
  6. sleep() peut être appelé de n'importe où. il n'y a pas d'exigence spécifique.

Ref: Différence entre l'attente et le sommeil

Extrait de code pour l'appel de la méthode wait and sleep

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

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

thread transition to different thread states


43
2017-12-28 06:18



Il y a quelques notes clés que je conclus après avoir travaillé sur wait and sleep, jetez d'abord un coup d'oeil sur sample en utilisant wait () et sleep ():

Exemple 1: en utilisant attendez() et dormir():

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();
}

Laissez la clarté des notes clés:

  1. Demander:
    • wait (): appel sur le thread en cours qui contient l'objet HandObject
    • sleep (): L'appel sur thread exécute la tâche get beer (la méthode de classe affecte donc le thread en cours)
  2. Synchronisé:
    • wait (): lors de l'accès multi-thread synchronisé même Object (HandObject) (Lorsque besoin de communication entre plusieurs threads (exécution du thread codage, exécution du thread get beer) accès sur le même objet HandObject)
    • sleep (): en attente de la condition pour continuer à exécuter (Waiting beer available)
  3. Maintenez le verrouillage:
    • wait (): relâchez le verrou pour que l'autre objet ait la chance de s'exécuter (HandObject est libre, vous pouvez faire un autre job)
    • sleep (): garde le verrou pendant au moins t fois (ou jusqu'à l'interruption) (Mon travail n'est toujours pas terminé, je continue à maintenir le verrou et j'attends une condition pour continuer)
  4. Condition de réveil:
    • wait (): jusqu'à l'appel notify (), notifyAll () de l'objet
    • sleep (): jusqu'à l'expiration du délai ou l'interruption de l'appel
  5. Et le dernier point est utiliser quand comme estani indiquer:

vous utilisez normalement sleep () pour la synchronisation du temps et wait () pour   synchronisation multi-thread.

Corrigez-moi si j'ai tort, s'il-vous plait.


28
2018-05-19 06:59



Différence entre wait () et sleep ()

  • La différence fondamentale est wait() est de Object et sleep() est la méthode statique de Thread.

  • La différence majeure est que wait() libère le verrou tout en sleep() ne libère aucun verrou en attendant.

  • le wait() est utilisé pour la communication inter-thread tout en sleep() est utilisé pour introduire une pause sur l'exécution, généralement.

  • le wait() devrait appeler de l'intérieur synchroniser ou sinon nous obtenons IllegalMonitorStateException  tandis que sleep()  peut appeler n'importe où.

  • Pour recommencer à filer à partir de wait(), vous devez appeler notify() ou notifyAll(). Alors que dans sleep(), Le thread démarre après l'intervalle ms / s spécifié.

Similitudes qui aident à comprendre

  • Les deux rend le fil actuel va dans le Non exécutable Etat.
  • Les deux sont native méthodes

21
2017-07-24 06:48



C'est une question très simple, car ces deux méthodes ont une utilisation totalement différente.

La principale différence est d'attendre pour libérer le verrou ou le moniteur pendant que le sommeil ne libère aucun verrou ou moniteur en attendant. Wait est utilisé pour la communication inter-thread tandis que sleep est utilisé pour introduire une pause lors de l'exécution. 

Ce n'était qu'une explication claire et simple, si vous voulez plus que cela, alors continuez à lire.

En cas de wait() thread de la méthode va dans l'état d'attente et il ne reviendra pas automatiquement jusqu'à ce que nous appelons le notify() méthode (ou notifyAll() si vous avez plus d'un thread en attente et que vous voulez réveiller tous ces threads). Et vous avez besoin d'un verrou synchronisé ou objet ou d'un verrou de classe pour accéder au wait() ou notify() ou notifyAll() méthodes Et une chose de plus, le wait() La méthode est utilisée pour la communication entre threads car si un thread passe en attente, vous aurez besoin d'un autre thread pour le réactiver.

Mais en cas de sleep() C'est une méthode qui est utilisée pour maintenir le processus pendant quelques secondes ou le temps que vous vouliez. Parce que vous n'avez pas besoin de provoquer notify() ou notifyAll() méthode pour récupérer ce thread. Ou vous n'avez pas besoin d'un autre thread pour rappeler ce thread. Comme si vous voulez que quelque chose se passe après quelques secondes comme dans un jeu après le tour de l'utilisateur, vous voulez que l'utilisateur attende jusqu'à ce que l'ordinateur joue alors vous pouvez mentionner le sleep() méthode.

Et une autre différence importante qui est souvent posée dans les interviews: sleep() appartient à Thread classe et wait() appartient à Object classe.

Ce sont toutes les différences entre sleep() et wait().

Et il y a une similitude entre les deux méthodes: elles sont toutes les deux vérifiées, donc vous devez essayer d'attraper ou de lancer pour accéder à ces méthodes.

J'espère que cela t'aidera.


18
2018-04-19 07:02



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

Thread.sleep() envoie le fil actuel dans le "Non exécutable" Etat   pour un certain temps. Le fil garde les moniteurs qu'il a acquis   - c'est-à-dire si le thread est actuellement dans un bloc ou une méthode synchronisée, aucun autre thread ne peut entrer dans ce bloc ou cette méthode. Si un autre thread appelle t.interrupt() il va réveiller le fil de couchage.

Notez que le sommeil est une méthode statique, ce qui signifie qu'il affecte toujours   le thread actuel (celui qui exécute la méthode sleep). UNE   erreur commune est d'appeler t.sleep() où t est un fil différent;   même alors, c'est le thread courant qui va dormir, pas le fil t.

t.suspend() est obsolète. L'utiliser est possible d'arrêter un fil autre   que le fil actuel. Un fil suspendu conserve tous ses moniteurs et   puisque cet état n'est pas interrompu, il est enclin à l'impasse.

object.wait() envoie le fil actuel dans le "Non exécutable" Etat,   comme sleep(), mais avec une torsion. L'attente est appelée sur un objet, pas un   fil; nous appelons cet objet "l'objet verrou". Avant lock.wait() est   appelé, le thread en cours doit se synchroniser sur l'objet lock; wait()   puis libère ce verrou et ajoute le fil à la "liste d'attente"   associé à la serrure. Plus tard, un autre thread peut se synchroniser sur le   même objet de verrouillage et appel lock.notify(). Cela réveille l'original,   fil d'attente. Fondamentalement, wait()/notify() est comme    sleep()/interrupt(), seul le thread actif n'a pas besoin d'un direct   pointeur sur le thread dormant, mais uniquement sur l'objet verrou partagé.


16
2017-11-05 03:34



Attendre et dormir sont deux choses différentes:

  • Dans sleep() le thread cesse de fonctionner pendant la durée spécifiée.
  • Dans wait() le thread cesse de fonctionner jusqu'à ce que l'objet attendu soit notifié, généralement par d'autres threads.

14
2018-06-24 06:53



sleep est une méthode de Thread, wait est une méthode de Object, alors wait/notify est une technique de synchronisation des données partagées en Java (en utilisant moniteur), mais sleep est une méthode simple de thread pour se mettre en pause.


10
2017-10-30 22:46