1328 votes

Différence entre wait() et sleep()

Quelle est la différence entre un et dans les Threads ?

Est ma compréhension qu’un - ing Thread est toujours en mode de fonctionnement et utilise les cycles CPU mais une - tion ne consomme pas de n’importe quel CPU cycles correctes ?

Pourquoi avons-nous tantet : Comment varie-t-elle en leur mise en œuvre à un niveau inférieur ?

897voto

oxbow_lakes Points 70013

Un wait peut être "réveillé" par un autre processus appelant notify sur le moniteur qui est attendu sur attendu qu'un sleep ne le peuvent pas. Aussi un wait (et notify) qui doit se produire dans un bloc synchronized sur le moniteur de l'objet alors qu' sleep n'est 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 en attente sur le moniteur) va se réveiller.

Vous pouvez également appeler notifyAll si plus d'un thread est en attente sur le moniteur, cela va se réveiller tous de la. Cependant, l'un des threads seront en mesure de saisir le moniteur (rappelez-vous que l' wait est en synchronized de l'îlot) et portent sur les autres sera alors bloqué jusqu'à ce qu'ils puissent acquérir de l'écran de verrouillage.

Un autre point est que vous appelez wait sur Object lui-même (c'est à dire que vous attendez sur un objet de l'écran) alors que vous, vous appelez sleep sur Thread.

Pourtant, un autre point est que vous pouvez obtenir les réveils intempestifs de wait (c'est à dire le fil qui est en attente reprend sans raison apparente). Vous devriez toujours wait , tandis que la filature sur une condition comme suit:

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

353voto

Robert Munteanu Points 31558

Une différence essentielle pas encore mentionnée est que, tandis qu’un Thread de couchage ne pas libérer les verrous qu’il détient, alors que l’attente libère le verrou sur l’objet qui `` est appelé.

268voto

E-rich Points 1904

J'ai trouvé ce lien utile (les références de ce post). Il met de la différence entre sleep(), wait(), et yield() en termes humains. (dans le cas où les liens ne marchent plus, j'ai inclus les post ci-dessous avec une annotation supplémentaire)

Tout cela a finalement fait son chemin jusqu'à l'OS, scheduler, qui mains timeslices pour les processus et les threads.

sleep(n) dit "j'en ai fini avec mon timeslice, et merci de ne pas me donner un autre pour au moins les n millisecondes." L'OS n'a même pas essayer de calendrier le thread en sommeil jusqu'à ce que demande le temps a passé.

yield() dit "j'en ai fini avec mon timeslice, mais j'ai encore du travail à faire." L'OS est libre de donner immédiatement le fil d'un autre timeslice, ou pour donner un autre thread ou processus de la CPU le rendement de filetage simplement abandonné.

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

Fils aussi perdre le reste de leur timeslice lorsqu'ils effectuent le blocage de IO et dans quelques autres circonstances. Si un thread fonctionne par le biais de l'ensemble de la timeslice, le système d'exploitation de force prend le contrôle à peu près comme si yield() avait été appelé, alors que d'autres processus peuvent s'exécuter.

Vous aurez rarement besoin yield(), mais si vous avez un calcul lourd app avec logique limites, l'insertion d'un yield() pourrait améliorer le système de réactivité (au détriment du temps - les changements de contexte, même juste pour l'OS et à l'arrière, ne sont pas libres). Mesure et de test en fonction des objectifs que vous de soins, comme toujours.

72voto

estani Points 1167

Il y a beaucoup de réponses ici, mais je ne pouvais pas trouver la distinction sémantique mentionné sur tout.

Il n'est pas sur le fil lui-même; les deux méthodes sont tenus de soutenir les différents cas d'utilisation.

sleep() envoie le Fil de dormir comme il était avant, c'est juste packs le contexte et s'arrête l'exécution pour une durée prédéfinie. C'est dans le but de le réveiller avant le temps, vous avez besoin de savoir le Fil de référence. Ce n'est pas une situation courante dans un environnement multi-thread. Il est principalement utilisé pour la synchronisation temporelle (par exemple, réveil exactement de 3,5 secondes) et/ou codée en dur de l'équité (juste dormir et de laisser les autres threads de travail).

wait(), au contraire, est un thread (ou message) mécanisme de synchronisation qui vous permet de notifier un Fil dont vous n'avez pas de référence stockée (ni de soins). Vous pouvez penser que c'est un publish-subscribe motif (wait == abonnez-vous et notify() == publier). Fondamentalement, l'aide notify() vous envoyez un message (qui pourrait même ne pas être reçu à tous et normalement vous n'avez pas de soins).

Pour résumer, vous utilisez habituellement sleep() de temps de synchronisation et d' wait() pour le multi-thread-synchronisation.

Ils pourraient être mises en œuvre de la même manière dans l'OS sous-jacent, ou pas du tout (comme les versions précédentes de Java n'avait pas vraiment de multithreading; probablement quelques petites VMs ne pas le faire). N'oubliez pas de Java s'exécute sur une machine virtuelle, de sorte que votre code sera transformé en quelque chose de différent en fonction de la VM/OS/HW, il fonctionne sur.

29voto

NguyenDat Points 2032

Il y a une différence clé de notes, j'ai conclure, après avoir travaillé sur d'attendre et de sommeil, tout d'abord un regard sur l'échantillon à l'aide wait() et sleep():

Exemple1: à l'aide de wait() et 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();
}

Laissez la clarté de certaines des principales remarques:

  1. Appelez sur:
    • wait(): Appel sur le thread actuel qui détiennent HandObject Objet
    • sleep(): Appel sur le Thread d'exécution de la tâche d'obtenir de la bière (est de la méthode de classe affectent donc sur le thread en cours d'exécution)
  2. Synchronisé:
    • wait(): lors d'une synchronisation multi-thread accès sur le même Objet (HandObject) (Quand le besoin de communication entre plusieurs threads (thread d'exécution de codage, thread d'exécution obtenir de la bière) accès sur le même objet HandObject )
    • sleep(): lors de l'attente de la condition de continuer à exécuter (en Attente de la bière disponible)
  3. Maintenez le verrou:
    • wait(): libère le verrou pour d'autres objets ont de la chance d'exécution (HandObject est libre, vous pouvez faire autre emploi)
    • sleep(): garder le verrou d'au moins t de temps (ou jusqu'à ce que l'interruption) (Mon travail pas encore fini, je vais continuer maintenez le verrou et l'attente qu'une condition pour continuer)
  4. Réveil à condition:
    • wait(): jusqu'à appeler notify(), notifyAll() de l'objet
    • sleep(): au moins jusqu'au moment d'expirer ou call interrompre
  5. Et le dernier point est à utiliser lorsque que estani indiquer:

vous utilisez normalement sleep() pour le temps de synchronisation et wait() pour multi-thread-synchronisation.

S'il vous plaît corrigez-moi si je me trompe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X