web-dev-qa-db-fra.com

Différence entre wait () et sleep ()

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

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

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

1141
Geek

Un wait peut être "réveillé" par un autre thread appelant notify sur le moniteur en attente alors qu'un sleep ne le peut pas. De plus, un wait (et notify) doit apparaître dans un bloc synchronized sur l'objet moniteur alors que sleep ne le 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 fil peut faire

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

(sur le même objet mon) et le premier thread (en supposant que ce soit le seul thread en attente sur le moniteur) se réveillera.

Vous pouvez également appeler notifyAll si plusieurs threads attendent sur le moniteur - cela réveillera tous . Cependant, un seul des threads pourra saisir le moniteur (rappelez-vous que le wait est dans un bloc synchronized) et continuer: les autres seront alors bloqués jusqu'à ce qu'ils puissent obtenir 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 des réveils parasites de wait (c’est-à-dire que le fil en attente reprend sans raison apparente). Vous devriez toujours wait tout en tournant sur une condition comme suit:

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

Une différence clé qui n’a pas encore été mentionnée est que, tout en étant en veille, un thread libère pas les verrous qu’il détient, tandis que l’attente libère le verrou sur l’objet sur lequel wait() est appelé.

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


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

J'ai trouvé ce post utile. Cela fait la différence entre Thread.sleep(), Thread.yield() et Object.wait() en termes humains. Citer:

Tout se résume finalement au planificateur du système d’exploitation, qui distribue des tranches de temps aux processus et aux threads.

sleep(n) dit "J'ai fini ma tranche de temps et s'il vous plaît, n'en donnez pas une autre pendant au moins n millisecondes." Le système d'exploitation n'essaie même pas de planifier le thread en veille tant que le temps demandé n'est pas écoulé.

yield() dit "J'ai terminé mon tranche de temps, mais j'ai encore du travail à faire." Le système d'exploitation est libre de donner immédiatement au thread une autre tranche de temps, ou de donner à un autre thread ou de traiter le processeur, le thread cédant venant d'être abandonné.

wait() dit "J'ai fini avec mon laps de temps. Ne me donnez pas un autre intervalle de temps jusqu'à ce que quelqu'un appelle notify (). ” Comme avec sleep(), le système d'exploitation n'essayera même pas de planifier votre tâche, sauf si appelle notify() (ou l'un des quelques scénarios de réveil qui se produisent).

Les fils perdent également le reste de leur tranche de temps lorsqu'ils bloquent IO et dans quelques autres circonstances. Si un thread fonctionne sur toute la tranche de temps, le système d'exploitation prend le contrôle de force, comme si yield() avait été appelé, de sorte que d'autres processus puissent s'exécuter.

Vous avez rarement besoin de yield(), mais si vous avez une application très lourde en calcul avec des limites logiques pour les tâches, insérer une yield() peut améliorer la réactivité du système (au détriment de temps - les changements de contexte, même juste pour le système d'exploitation et inversement, ne sont pas libres). Comme toujours, mesurez et testez par rapport aux objectifs qui vous tiennent à cœur.

227
E-rich

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

Ce n'est pas sur le 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 en veille comme avant, il compresse simplement le contexte et cesse de s'exécuter pendant une durée prédéfinie. 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 multi-thread. Il est principalement utilisé pour la synchronisation temporelle (par exemple, réveil exactement 3,5 secondes) et/ou une équité codée en dur (veillez un instant et laissez les autres threads fonctionner).

wait(), au contraire, est un mécanisme de synchronisation de threads (ou de messages) qui vous permet de notifier un thread dont vous ne possédez aucune référence (ni aucun soin). Vous pouvez le considérer comme un modèle de publication/abonnement (wait == subscribe et notify() == publish). En utilisant essentiellement notify (), vous envoyez un message (qui pourrait même ne pas être reçu du tout et normalement, vous ne vous en souciez pas).

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

Ils peuvent être implémentés de la même manière dans le système d'exploitation sous-jacent, ou pas du tout (car les versions précédentes de Java ne comportaient pas de véritable multithreading; probablement de petites machines virtuelles ne le font pas non plus). N'oubliez pas que Java s'exécute sur une machine virtuelle. Votre code sera transformé en quelque chose de différent en fonction de la machine virtuelle/système d'exploitation/matériel sur lequel il s'exécute.

65
estani

Ici, j'ai énuméré quelques différences importantes entre les méthodes wait() et sleep().
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).

wait ()

  1. La méthode wait() libère le verrou.
  2. wait() est la méthode de Object class.
  3. wait() est la méthode non statique - public final void wait() throws InterruptedException { //...}
  4. wait() doit être notifié par les méthodes notify() ou notifyAll().
  5. La méthode wait() doit être appelée depuis une boucle pour traiter les fausses alarmes.

  6. La méthode wait() doit être appelée à partir d'un contexte synchronisé (c'est-à-dire une méthode ou un bloc synchronisé), sinon elle lancera IllegalMonitorStateException

sommeil ()

  1. La méthode sleep() ne libère pas le verrou.
  2. sleep() est la méthode de Java.lang.Thread class.
  3. sleep() est la méthode statique - public static void sleep(long millis, int nanos) throws InterruptedException { //... }
  4. après la durée spécifiée, sleep() est terminé.
  5. sleep() Mieux vaut ne pas appeler depuis la 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 attente et sommeil

Extrait de code pour l'appel des méthodes d'attente et de veille

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

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

thread transition to different thread states

49
roottraveller

Il y a quelques différences entre les notes clés que je conclus après avoir travaillé sur wait et sleep, jetez d'abord un coup d'œil sur l'échantillon en utilisant wait () et sleep ():

Exemple1 : utiliser attendre () et sommeil ():

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é quelques notes clés:

  1. Appelez le :
    • wait (): Appel sur le thread actuel contenant l'objet HandObject
    • sleep (): Appelez la tâche d'exécution Thread get get beer
  2. Synchronisé :
    • wait (): lorsqu’un multi-thread synchronisé accède au même objet (HandObject) (lorsqu’il faut une communication entre plusieurs threads (codage d’exécution de threads, accès de threads exécuté), accès au même objet HandObject)
    • sleep (): en attente de la condition pour continuer à s'exécuter (En attente de bière disponible)
  3. Tenir le verrou :
    • wait (): libère le verrou pour qu'un autre objet ait la chance de s'exécuter (HandObject est libre, vous pouvez faire un autre travail)
    • sleep (): conserve le verrou pendant au moins t fois (ou jusqu’à l’interruption) (mon travail n’est toujours pas terminé, je continue de maintenir le verrouillage et d’attendre certaines conditions pour continuer)
  4. Condition de réveil :
    • wait (): jusqu'à l'appel notify (), notifyAll () de l'objet
    • sleep (): au moins jusqu'à l'expiration du temps ou l'interruption de l'appel
  5. Et le dernier point est utiliser quand as estani indique:

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

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

28
NguyenDat

Différence entre wait () et sleep ()

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

  • La principale différence est que wait() libère le verrou tandis que sleep() ne lâche aucun verrou pendant l’attente.

  • wait() est utilisé pour la communication inter-thread tandis que sleep() est utilisé pour introduire une pause lors de l'exécution, en général.

  • wait() devrait être appelé de l'intérieur à synchroniser ou nous obtenons un IllegalMonitorStateException, alors que sleep() peut être appelé n'importe où.

  • Pour relancer un fil à partir de wait(), vous devez appeler notify() ou notifyAll(). Comme pour sleep(),, le thread est démarré après un intervalle de temps spécifié.

Similitudes

  • Les deux font en sorte que le thread actuel passe à l'état Not Runnable.
  • Les deux méthodes sont native.
22
Premraj

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 que le verrou ou le moniteur soit libéré pendant que la mise en veille ne libère aucun verrou ni le moniteur pendant l'attente. Wait est utilisé pour la communication inter-thread tandis que le mode veille est utilisé pour introduire une pause dans l'exécution.

Ceci était juste une explication claire et basique, si vous voulez plus que cela, continuez à lire.

Dans le cas de wait(), le thread de méthode passe en état d'attente et il ne reviendra pas automatiquement tant que nous n'aurons pas appelé la méthode notify() (ou notifyAll() si vous avez plus d'un thread en attente et vous voulez réveiller tous ces fils). Et vous avez besoin d'un verrou synchronisé, d'objet ou de classe pour accéder aux méthodes wait() ou notify() ou notifyAll(). Et encore une chose, la méthode wait() est utilisée pour la communication inter-thread, car si un thread passe en attente, vous aurez besoin d'un autre thread pour l'activer.

Mais dans le cas de sleep(), il s’agit d’une méthode utilisée pour mettre en attente le processus pendant quelques secondes ou la durée souhaitée. Parce que vous n'avez pas besoin de provoquer une méthode notify() ou notifyAll() pour récupérer ce fil. Ou vous n'avez pas besoin d'un autre thread pour rappeler ce thread. Par exemple, 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 celui-ci attende que l'ordinateur démarre, puis vous pouvez mentionner la méthode sleep().

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

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

Et il y a une similitude entre les deux méthodes: les deux sont des instructions vérifiées, vous devez donc essayer des catch ou des jets pour accéder à ces méthodes.

J'espère que cela t'aidera.

18
Vikas Gupta

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

Thread.sleep() envoie le thread en cours à l'état "Non exécutable" pendant un certain temps. Le thread conserve les moniteurs qu’il a acquis - c’est-à-dire si le thread est actuellement dans un bloc ou une méthode synchronisé, aucun autre thread ne peut entrer dans ce bloc ou cette méthode. Si un autre thread appelle t.interrupt() , le thread en veille sera réactivé.

Notez que le sommeil est une méthode statique, ce qui signifie qu’elle affecte toujours le thread actuel (celui qui exécute la méthode de veille). Une erreur courante consiste à appeler t.sleep() où t est un autre thread; même dans ce cas, c'est le thread actuel qui va dormir, pas le thread t.

t.suspend() est obsolète. Il est possible d’arrêter un thread autre que le thread actuel. Un thread suspendu conserve tous ses moniteurs et, cet état n'étant pas interruptible, il est sujet à des blocages.

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

16
om singh

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 à attendre soit notifié, généralement par d'autres threads.
14
Itay Maman

sleep est une méthode de Thread, wait est une méthode de Object, donc wait/notify est une technique de synchronisation des données partagées dans Java. _ (using monitor ), mais sleep est une méthode simple de thread pour se mettre en pause.

11
pvllnspk

sleep () est une méthode utilisée pour mettre le processus en attente pendant quelques secondes ou l'heure désirée, mais en cas d'utilisation de la méthode wait (), le thread y passe. en attente et il ne reviendra pas automatiquement tant que nous n’aurons pas appelé notify () ou notifyAll ().

La différence majeure est que wait () libère le verrou ou le moniteur en sleep () n'émet aucun verrou ni moniteur pendant l'attente. Wait est utilisé pour la communication inter-thread tandis que le sommeil est utilisé pour introduire une pause lors de l'exécution, en général.

Thread.sleep () envoie le thread actuel à l'état "Non exécutable" pendant un certain temps. Le thread conserve les moniteurs qu’il a acquis - c’est-à-dire si le thread est actuellement dans un bloc ou une méthode synchronisé, aucun autre thread ne peut entrer dans ce bloc ou cette méthode. Si un autre thread appelle t.interrupt (), il réactivera le thread en veille. Notez que le sommeil est une méthode statique, ce qui signifie qu’elle affecte toujours le thread actuel (celui qui exécute la méthode de veille). Une erreur courante consiste à appeler t.sleep () où t est un autre thread; même dans ce cas, c'est le thread actuel qui va dormir, pas le thread t.

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

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

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

Laisser classer tous les points ci-dessus:

Call on:

  • wait (): Appelle un objet. le thread actuel doit se synchroniser sur l'objet verrou.
  • sleep (): Appeler un fil; toujours en train d'exécuter le fil.

Synchronized:

  • wait (): lorsque plusieurs threads synchronisés ont accès au même objet un par un.
  • sleep (): lorsque plusieurs threads synchronisés attendent la fin du sommeil du thread en veille.

Hold lock:

  • wait (): relâche le verrou pour que d'autres objets puissent s'exécuter.
  • sleep (): conserve le verrou pendant au moins t fois si le délai d'expiration spécifié ou si quelqu'un l'interrompt.

Wake-up condition:

  • wait (): jusqu'à l'appel de notify (), notifyAll () de l'objet
  • sleep (): au moins jusqu'à l'expiration du délai ou un appel interrompu ().

Usage:

  • sleep (): pour la synchronisation de l'heure et;
  • wait (): pour la synchronisation multi-thread.

Réf: diff sleep et wait

8
Reegan Miranda

Les méthodes wait et sleep sont très différentes:

  • sleep n'a aucun moyen de "se réveiller",
  • alors que wait a une façon de se "réveiller" pendant la période d'attente, par un autre thread appelant notify ou notifyAll .

À bien y penser, les noms sont déroutants à cet égard; Cependant, sleep est un nom standard et wait est semblable à WaitForSingleObject ou WaitForMultipleObjects dans l'API Win.

6
Roee Adler

De cet article: http://javaconceptoftheday.com/difference-between-wait-and-sleep-methods-in-Java/

wait () Méthode.

1) Le thread qui appelle la méthode wait () libère le verrou qu’elle détient.

2) Le thread récupère le verrou après que d'autres threads ont appelé les méthodes notify () ou notifyAll () sur le même verrou.

3) La méthode wait () doit être appelée dans le bloc synchronisé.

4) La méthode wait () est toujours appelée sur les objets.

5) Les threads en attente peuvent être réveillés par d'autres threads en appelant les méthodes notify () ou notifyAll ().

6) Pour appeler la méthode wait (), le thread doit avoir le verrouillage d'objet.

méthode sleep ()

1) Le thread qui appelle la méthode sleep () ne libère pas le verrou qu’elle détient.

2) La méthode sleep () peut être appelée à l'intérieur ou à l'extérieur du bloc synchronisé.

3) La méthode sleep () est toujours appelée sur les threads.

4) Les fils en sommeil ne peuvent pas être réveillés par d'autres fils. Si cela est fait, le thread lèvera une exception InterruptedException.

5) Pour appeler la méthode sleep (), le thread n'a pas besoin de verrouiller l'objet.

5
user2485429

En termes simples, wait est wait jusqu'à ce qu'un autre thread vous appelle alors que sleep est "n'exécutez pas la prochaine instruction" pendant une période donnée.

De plus, sleep est une méthode statique dans la classe Thread et fonctionne sur le thread, tandis que wait () est dans la classe Object et est appelé sur un objet.

Autre point, lorsque vous appelez wait sur un objet, le thread impliqué synchronise l’objet puis attend. :)

5
Ratnesh Maurya

Une grande différence potentielle entre sommeil/interruption et attente/notification est que

Générer une exception lorsqu'il n'est pas nécessaire est inefficace. Si vous avez des fils qui communiquent entre eux à un débit élevé, de nombreuses exceptions seraient générées si vous appeliez des interruptions tout le temps, ce qui représente un gaspillage total de ressources processeur.

4
Mark
  1. wait() est une méthode de Object class.
    sleep() est une méthode de Thread class.

  2. sleep() permet au thread de passer à l'état sleep pendant x millisecondes.
    Quand un thread passe en état de veille it doesn’t release the lock.

  3. wait() permet au thread de relâcher le verrou et goes to suspended state.
    Ce thread sera actif quand une méthode notify() ou notifAll() sera appelée pour le même objet.

4
VdeX

Ici wait () sera dans l'état d'attente jusqu'à ce qu'il soit averti par un autre Thread, mais où sleep () aura un certain temps..après, il passera automatiquement à l'état Prêt ...

3
Rakhi Jaligama

Les méthodes sont utilisées pour différentes choses.

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

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

Thread.sleep (n) peut être interrompu, mais Object.wait () doit être être averti. Il est possible de spécifier le temps d'attente maximal: Object.wait(5000) afin qu'il soit possible d'utiliser wait pour, euh, sleep, mais vous devrez alors vous embêter avec les verrous.

Aucune des méthodes n'utilise le processeur pendant le sommeil/l'attente.

Les méthodes sont implémentées en utilisant du code natif, en utilisant des constructions similaires mais pas de la même manière.

Recherchez vous-même: Le code source des méthodes natives est-il disponible? Le fichier /src/share/vm/prims/jvm.cpp est le point de départ ...

3
KarlP

Attendre () et dormir () Différences?

Thread.sleep () Une fois son travail terminé, il ne libère que le verrou à tout le monde. jusqu'à ce que son ne jamais libérer le verrou à personne.

  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 () Lorsqu'il passera en attente, il lâchera la clé et attendra quelques secondes en fonction du paramètre.

Par exemple:

vous prenez le café dans votre main droite, vous pouvez prendre une autre personne de la même main, quand vous posez alors seulement un autre objet du même type ici. aussi. c'est dormir () tu dors le temps tu ne travailles pas, tu ne fais que dormir .. pareil ici aussi.

attendez(). quand vous êtes couché et prenez un autre moyen pendant que vous attendez, c'est attendre

vous jouez un film ou quoi que ce soit dans votre système même en tant que lecteur, vous ne pouvez pas jouer plus d'un droit à la fois, c'est son ici, quand vous fermez et choisissez un autre film ou chanson signifie que vous attendez

3
VISALIG

wait libère le verrou et sleep ne le supprime pas. Un thread en attente est éligible pour se réveiller dès que notify ou notifyAll est appelé. Mais dans le cas de sleep, le fil garde le verrou et il ne sera éligible qu'une fois le temps de sommeil écoulé.

3
shikjohari

Vous avez raison - Sleep () provoque la mise en veille de ce thread et le processeur s’éteint pour traiter d’autres threads (autrement connus sous le nom de commutation de contexte), ce qui, je le crois, permet au processeur de traiter le thread actuel.

Nous avons les deux parce que, même s'il peut sembler judicieux de laisser d'autres personnes utiliser le processeur alors que vous ne l'utilisez pas, le changement de contexte entraîne une surcharge. En fonction de la durée de veille, il peut être plus coûteux en cycles de processeur. pour changer de thread que ce soit simplement que votre thread ne fasse rien pendant quelques ms.

Notez également que le sommeil force le changement de contexte.

De plus, en général, il n'est pas possible de contrôler le changement de contexte. Pendant le délai d'attente, le système d'exploitation peut choisir (et attend plus longtemps) de traiter d'autres threads.

3
Justin

À mon avis, la principale différence entre les deux mécanismes est que veille/interruption est le moyen le plus fondamental de gérer les threads, alors que wait/notify est une abstraction destinée à faciliter l'intercommunication de threads. Cela signifie que dormir/interrompre peut faire n'importe quoi, mais cette tâche spécifique est plus difficile à faire.

Pourquoi attendre/notifier est-il plus approprié? Voici quelques considérations personnelles:

  1. Il impose la centralisation. Il permet de coordonner la communication entre un groupe de threads avec un seul objet partagé. Cela simplifie beaucoup le travail.

  2. La synchronisation est appliquée. Parce que le programmeur encapsule l'appel d'attendre/notifier dans un bloc synchronisé.

  3. Il est indépendant du fil Origine et du nombre. Avec cette approche, vous pouvez ajouter plusieurs threads de façon arbitraire sans éditer les autres threads ni conserver une trace de ceux existants. Si vous avez utilisé veille/interruption, vous devez d’abord conserver les références aux threads en veille, puis les interrompre un à un, à la main.

Voici un exemple tiré de la vraie vie: c’est un restaurant classique et la méthode que le personnel utilise pour communiquer entre eux: les serveurs laissent les demandes des clients dans un lieu central (un tableau en liège, une table, etc.), sonner une cloche, et les travailleurs de la cuisine viennent pour prendre de telles demandes. Une fois que tous les cours sont prêts, le personnel de la cuisine sonne à nouveau pour que les serveurs soient au courant et les apportent aux clients.

2
negora

Depuis la page de documentation Oracle sur wait () méthode de Object:

public final void wait()
  1. Amène le thread en cours à attendre jusqu'à ce qu'un autre thread appelle la méthode notify() ou la méthode notifyAll() pour cet objet. En d'autres termes, cette méthode se comporte exactement comme si elle effectuait simplement l'appel wait(0).
  2. Le thread actuel doit posséder le moniteur de cet objet. Le thread libère la propriété de ce moniteur et attend jusqu'à ce qu'un autre thread informe les threads en attente sur le moniteur de cet objet de se réveiller
  3. des interruptions et des réveils parasites sont possibles
  4. Cette méthode ne doit être appelée que par un thread propriétaire du moniteur de cet objet

Cette méthode jette

  1. IllegalMonitorStateException - si le thread actuel n'est pas le propriétaire du moniteur de l'objet.

  2. InterruptedException - si un thread a interrompu le thread actuel avant ou pendant que le thread actuel attendait une notification. Le statut interrompu du thread en cours est effacé lorsque cette exception est levée.

De la page de documentation Oracle sur sleep () méthode de Thread class:

public static void sleep(long millis)
  1. Fait suspendre temporairement l'exécution du thread en cours d'exécution pendant le nombre de millisecondes spécifié, sous réserve de la précision et de l'exactitude des temporisateurs et programmateurs du système.
  2. Le thread ne perd la propriété d'aucun des moniteurs.

Cette méthode jette:

  1. IllegalArgumentException - si la valeur en millis est négative

  2. InterruptedException - si un thread a interrompu le thread en cours. Le statut interrompu du thread en cours est effacé lorsque cette exception est levée.

Autre différence clé:

wait() est une méthode non statique (méthode d'instance) contrairement à la méthode statique sleep() (méthode de classe).

2
Ravindra babu

Exemple sur le sommeil ne libère pas le verrou et attend que le

Ici il y a deux classes:

  1. Main: Contient la méthode principale et deux threads.
  2. Singleton: Il s'agit d'une classe singleton avec deux méthodes statiques, getInstance () et 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();
    
     }
    }
    

et

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;

 }
}

Maintenant, lancez cet exemple, vous obtiendrez ci-dessous la sortie:

_instance :null
Both singleton are same

Ici, les instances Singleton créées par threadA et threadB sont identiques. Cela signifie que threadB attend à l'extérieur jusqu'à ce que threadA lâche le verrou.

Maintenant changez le Singleton.Java en commentant Thread.sleep (500); méthode et non commentée Singleton.class.wait (500); . Ici à cause de Singleton.class.wait (500); La méthode threadA libérera tous les verrous acquis et passera à l'état "non exécutable", threadB obtiendra la modification à entrer dans le bloc synchronisé.

Maintenant, lancez à nouveau:

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

Ici, les instances Singleton créées par threadA et par threadB ne sont pas identiques, car threadB a dû changer pour entrer dans un bloc synchronisé et après 500 millisecondes, threadA a démarré à partir de sa dernière position et a créé un autre objet Singleton.

2
Dhiral Pandya

La méthode sleep() a pour effet que le thread en cours passe de l'état d'exécution à l'état de blocage pendant un temps spécifié. Si le thread actuel a le verrou d'un objet, il le maintient, ce qui signifie que les autres threads ne peuvent exécuter aucune méthode synchronisée dans cet objet de classe.

La méthode wait() a pour effet que le thread actuel passe à l'état de bloc pendant une durée spécifiée ou jusqu'à notification, mais dans ce cas, le thread libère le verrou de l'objet (ce qui signifie que d'autres threads peuvent exécuter toutes les méthodes synchronisées de l'appelant. objet.

2
User10001

Devrait être appelé à partir d'un bloc synchronisé: La méthode wait() est toujours appelée à partir d'un bloc synchronisé, c'est-à-dire que la méthode wait() doit verrouiller l'objet de contrôle avant objet sur lequel il s'appelle. Mais la méthode sleep() peut être appelée de l'extérieur du bloc synchronisé, c'est-à-dire que la méthode sleep() ne nécessite aucun moniteur d'objet.

IllegalMonitorStateException: si la méthode wait() est appelée sans acquérir le verrou d'objet, alors que IllegalMonitorStateException est lancé à l'exécution, mais sleep() méthode ne jette jamais une telle exception.

Appartient à quelle classe: _ la méthode wait() appartient à Java.lang.Object classe mais la méthode sleep() à Java.lang.Thread classe.

Appelé sur un objet ou un fil: La méthode wait() est appelée sur les objets mais la méthode sleep() est appelée sur les threads et non les objets.

Etat du thread: lorsque la méthode wait() est appelée sur un objet, le thread qui a gardé le moniteur de l'objet passe de l'état en attente à l'état actif et peut revenir à l'état en cours d'exécution. uniquement lorsque la méthode notify() ou notifyAll() est appelée sur cet objet. Et plus tard, le planificateur de threads planifie ce thread pour passer de l'état d'exécution à l'état d'exécution. Lorsque sleep() est appelé sur le thread, il passe de l'état d'exécution à l'état d'attente et peut revenir à l'état d'exécution lorsque le temps de repos est écoulé.

Lorsqu'il est appelé à partir d'un bloc synchronisé: lorsque la méthode wait() est appelée, le thread quitte le verrouillage d'objet. Mais la méthode sleep() lorsqu'elle est appelée à partir d'un bloc synchronisé ou d'un thread de méthode ne laisse pas le verrouillage d'objet.

Pour plus référence

2
AVI

En fait, tout cela est clairement décrit dans Java docs (mais je ne m'en suis rendu compte qu'après avoir lu les réponses).

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

wait () - Le thread actuel doit posséder le moniteur de cet objet. Le thread libère la propriété de ce moniteur et attend jusqu'à ce qu'un autre thread informe les threads en attente sur le moniteur de cet objet de se réveiller via un appel à la méthode notify ou à la méthode notifyAll. Le thread attend ensuite jusqu'à ce qu'il puisse récupérer la propriété du moniteur et reprend l'exécution.

sleep () - Met en veille le serveur en cours d'exécution (arrête temporairement l'exécution de l'exécution) pendant le nombre de millisecondes spécifié, sous réserve de la précision et de l'exactitude des temporisateurs et programmateurs du système. Le thread ne perd pas la propriété des moniteurs.

1
TT_
  • La méthode wait(1000) provoque l’endormissement du thread actuel pendant une seconde au maximum .
    • Un thread peut dormir moins d'une seconde s'il reçoit l'appel à la méthode notify() ou notifyAll().
  • L’appel de sleep(1000) provoque l’endormissement du thread en cours pendant exactement 1 seconde .
    • De plus, le thread en veille ne verrouille aucune ressource . Mais attendre le fil fait.
1
Rupesh

wait() est donné dans une méthode synchronisée alors que sleep() est donné dans une méthode non synchronisée car la méthode wait() libère le verrou sur l'objet mais sleep() ou yield() libère-t-il la lock().

1
Aravind Mano

wait() avec une valeur de délai d'attente peut se réveiller une fois la valeur de délai écoulée ou notifier celle qui est antérieure (ou l'interrompre également), alors qu'un sleep() réveille la valeur de délai écoulé ou interrompre la première. wait() sans valeur de délai d'attente attendra jusqu'à ce qu'il soit notifié ou interrompu.

1
Dr. Debasish Jana

Supposons que vous entendez des chansons.

Tant que la chanson en cours est en cours d'exécution, la chanson suivante ne sera pas lue, par exemple Sleep () appelée par la chanson suivante.

Si vous terminez la chanson, la lecture s'arrêtera et jusqu'à ce que vous sélectionniez le bouton de lecture (notify ()), la lecture sera interrompue, c'est-à-dire wait () appelé par la chanson en cours.

Dans ce cas, les chansons vont aux états d'attente.

0
pavan