java wait




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

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

Est-ce que je comprends qu'un thread wait() -ing est toujours en mode de fonctionnement et utilise des cycles de CPU mais un sleep() -ing ne consomme pas de cycles CPU corrects?

Pourquoi avons-nous à la fois wait() et sleep() : comment leur implémentation varie-t-elle à un niveau inférieur?


Différence entre wait () et sleep ()

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

  • La principale différence est que wait() libère le verrou tandis que sleep() ne libère aucun verrou en attente.

  • Le wait() est utilisé pour la communication inter-thread tandis que sleep() est utilisé pour introduire une pause à l'exécution, généralement.

  • IllegalMonitorStateException wait() devrait appeler de l'intérieur synchronize, sinon on obtient IllegalMonitorStateException pendant que sleep() peut appeler n'importe où.

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

Similitudes qui aident à comprendre

  • Les deux font que le thread actuel passe à l'état Non exécutable .
  • Les deux sont native méthodes native .

dormir

  • Il fait dormir le thread en cours d'exécution pendant un certain temps.
  • Sa précision dépend des minuteurs du système et des planificateurs.
  • Il conserve les moniteurs qu'il a acquis, donc s'il est appelé à partir du contexte synchronisé, aucun autre thread ne peut entrer dans ce bloc ou cette méthode.
  • Si nous appelons la méthode interrupt (), elle réveillera le thread endormi.

Attendez

  • Il provoque l'attente du thread en cours jusqu'à ce qu'un autre thread invoque la méthode notify () ou la méthode notifyAll () pour cet objet
  • Il doit être appelé à partir du contexte synchronisé, c'est-à-dire du bloc ou de la méthode. Cela signifie qu'avant l'appel de la méthode wait (), le thread en cours doit avoir un verrou sur cet objet.
  • Il libère le verrou sur l'objet sur lequel il est appelé et ajouté à la liste d'attente, ainsi un autre thread peut acquérir un verrou sur l'objet.

Attendre et dormir sont deux choses différentes:

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

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 basique, si vous voulez plus que cela, continuez à lire.

Dans le cas de la méthode wait() , le thread passe en état d'attente et il ne reviendra pas automatiquement tant que nous n'appellerons pas la méthode notify() (ou notifyAll() si vous avez plus d'un thread en attente et que vous voulez ce fil). Et vous avez besoin d'un verrou synchronisé ou d'un objet ou d'un verrou 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 état d'attente, vous aurez besoin d'un autre thread pour réveiller ce thread.

Mais dans le 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 une méthode notify() ou notifyAll() 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, vous pouvez mentionner la méthode sleep() .

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

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.


En termes simples, l'attente est attendue jusqu'à ce que d'autres threads vous invoquent alors que sleep est "ne pas exécuter l'instruction suivante" pendant une période donnée.

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

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


Ici, j'ai énuméré quelques différences importantes entre les méthodes wait() et sleep() .
PS: Cliquez aussi 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. wait() méthode wait() libère le verrou.
  2. wait() est la méthode de la classe Object .
  3. wait() est la méthode non statique - public final void wait() throws InterruptedException { //...}
  4. wait() doit être notifié par notify() ou notifyAll() .
  5. wait() méthode wait() doit être appelée à partir d'une boucle afin de gérer les fausses alarmes.

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

sleep()

  1. sleep() méthode sleep() ne libère pas le verrou.
  2. sleep() est la méthode de la classe java.lang.Thread .
  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() préférable de ne pas appeler à partir de la boucle (c. -à- d. 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 Wait et Sleep

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    
}


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

  1. Appelez :
    • 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 la serrure :
    • 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 (): garder le verrou pendant au moins t fois (ou jusqu'à 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 l' utilisation quand as estani indique:

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

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


J'ai trouvé ce lien utile (qui référence ce post ). Il 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 au planificateur du système d'exploitation, qui distribue les délais aux processus et aux threads.

sleep(n) dit "J'en ai fini avec mon timelice, et s'il vous plait n'en donnez pas un autre pendant au moins n millisecondes." Le système d'exploitation n'essaye même pas de programmer le thread endormi jusqu'à ce que le temps demandé soit 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 au thread un autre timeslice, ou de donner un autre thread ou de traiter le CPU. .

.wait() dit "j'en ai fini avec mon timeslice. Ne me donnez pas un autre timeslice jusqu'à ce que quelqu'un appelle notify (). " Comme avec sleep() , le système d'exploitation n'essaiera même pas de planifier votre tâche à moins que quelqu'un appelle notify() (ou l'un des autres scénarios de réveil).

Les threads perdent également le reste de leur temps lorsqu'ils effectuent des opérations d'entrave et dans d'autres circonstances. Si un thread fonctionne sur l'intégralité du timelice, le système d'exploitation prend le contrôle de manière forcée, comme si yield() avait été appelé, afin que d'autres processus puissent s'exécuter.

Vous avez rarement besoin de yield() , mais si vous avez une application lourde avec des limites de tâches logiques, l'insertion d'un yield() peut améliorer la réactivité du système (au détriment des changements de temps, même pour le système d'exploitation). t libre). Mesurez et testez les objectifs qui vous intéressent, comme toujours.


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

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

(Sur le même objet mon ) 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 est en attente sur le moniteur - cela les réveillera tous . Cependant, un seul des threads sera capable d'attraper le moniteur (rappelez-vous que l' wait est dans un bloc synchronized ) et continuez - 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 on Object (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 d' wait (c'est-à-dire que le thread qui attend reprend sans raison apparente). Vous devriez toujours wait en tournant sur une condition comme suit:

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

Une différence clé non encore mentionnée est que pendant le sommeil, un Thread ne libère pas les verrous qu'il contient, 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
}

Vous avez raison - Sleep () provoque la mise en veille de ce thread et le CPU s'éteint et traite d'autres threads (autrement dit le changement de contexte) alors que je crois que Wait garde le processeur traitant le thread courant.

Nous avons les deux parce que, bien qu'il puisse sembler logique de laisser d'autres personnes utiliser le processeur pendant que vous ne l'utilisez pas, il y a un changement de contexte - en fonction de la durée du sommeil, il peut être plus cher dans les cycles du processeur. pour changer de threads que c'est simplement avoir votre thread ne rien faire pendant quelques ms.

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

En outre - en général, il n'est pas possible de contrôler le changement de contexte - pendant l'attente, l'OS peut (et attendra plus longtemps) choisir de traiter d'autres threads.


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

sleep envoie le thread en cours dans l'état "Not Runnable" pendant un certain temps. Le thread conserve les moniteurs qu'il a acquis - c'est-à-dire que si le thread est actuellement dans un bloc ou une méthode synchronisés, aucun autre thread ne peut entrer dans ce bloc ou cette méthode. Si un autre thread appelle t.interrupt() il réveillera le thread endormi.

Notez que sleep est une méthode statique, ce qui signifie qu'elle affecte toujours le thread en cours (celui qui exécute la méthode sleep). Une erreur courante est d'appeler t.sleep() où t est un thread 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 thread suspendu conserve tous ses moniteurs et puisque cet état n'est pas interrompu, il est enclin à l'impasse.

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


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


wait méthodes d' wait et de sleep sont très différentes:

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

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


Should be called from synchronized block : wait() method is always called from synchronized block ie wait() method needs to lock object monitor before object on which it is called. But sleep() method can be called from outside synchronized block ie sleep() method doesn't need any object monitor.

IllegalMonitorStateException : if wait() method is called without acquiring object lock than IllegalMonitorStateException is thrown at runtime, but sleep() method never throws such exception.

Belongs to which class : wait() method belongs to java.lang.Object class but sleep() method belongs to java.lang.Thread class.

Called on object or thread : wait() method is called on objects but sleep() method is called on Threads not objects.

Thread state : when wait() method is called on object, thread that holded object's monitor goes from running to waiting state and can return to runnable state only when notify() or notifyAll() method is called on that object. And later thread scheduler schedules that thread to go from from runnable to running state. when sleep() is called on thread it goes from running to waiting state and can return to runnable state when sleep time is up.

When called from synchronized block : when wait() method is called thread leaves the object lock. But sleep() method when called from synchronized block or method thread doesn't leaves object lock.

For More Reference


sleep () est une méthode utilisée pour maintenir le processus pendant quelques secondes ou le temps que vous vouliez, mais dans le cas de wait (), le thread de la méthode passe en attente et ne reviendra pas automatiquement tant que nous n'appellerons pas notify () ou notifyAll ().

La principale différence est que wait () libère le verrou ou le moniteur alors que sleep () ne libère aucun verrou ou moniteur en attente. Wait est utilisé pour la communication inter-thread tandis que sleep est utilisé pour introduire une pause à l'exécution, généralement.

Thread.sleep () envoie le thread en cours dans l'état "Not Runnable" 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ée, aucun autre thread ne peut entrer dans ce bloc ou cette méthode. Si un autre thread appelle t.interrupt (), il réveillera le thread endormi. Notez que sleep est une méthode statique, ce qui signifie qu'elle affecte toujours le thread en cours (celui qui exécute la méthode sleep). Une erreur courante est d'appeler t.sleep () où t est un thread différent; même alors, c'est le thread courant qui va dormir, pas le fil t.

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

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

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

Laissez catégoriser tous les points ci-dessus:

Call on:

  • wait (): appelle sur un objet; le thread en cours doit se synchroniser sur l'objet lock.
  • sleep (): appelle sur un sujet; toujours en cours d'exécution thread.

Synchronized:

  • wait (): lors de la synchronisation, plusieurs threads accèdent au même objet un par un.
  • sleep (): lors de la synchronisation, plusieurs threads attendent le sommeil sur le thread en veille.

Hold lock:

  • wait (): libère le verrou pour que d'autres objets puissent s'exécuter.
  • sleep (): garde le verrou pendant au moins t fois si timeout est spécifié ou quelqu'un interrompt.

Wake-up condition:

  • wait (): jusqu'à l'appel notify (), notifyAll () de l'objet
  • sleep (): jusqu'à ce que le temps expire ou appelle l'interruption ().

Usage:

  • sleep (): pour la synchronisation temporelle et;
  • wait (): pour la synchronisation multi-thread.

Ref: diff sleep et wait


From oracle documentation page on wait() method of Object :

public final void wait()
  1. Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0) .
  2. The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up
  3. interrupts and spurious wakeups are possible
  4. This method should only be called by a thread that is the owner of this object's monitor

This method throws

  1. IllegalMonitorStateException - if the current thread is not the owner of the object's monitor.

  2. InterruptedException - if any thread interrupted the current thread before or while the current thread was waiting for a notification. The interrupted status of the current thread is cleared when this exception is thrown.

From oracle documentation page on sleep() method of Thread class:

public static void sleep(long millis)
  1. Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.
  2. The thread does not lose ownership of any monitors.

This method throws:

  1. IllegalArgumentException - if the value of millis is negative

  2. InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

Other key difference:

wait() is a non-static method (instance method) unlike static method sleep() (class method).


Here wait() will be in the waiting state till it notify by another Thread but where as sleep() will be having some time..after that it will automatically transfer to the Ready state...


Lets assume you are hearing songs.

As long as the current song is running, the next song wont play, ie Sleep() called by next song

If you finish the song it will stop and until you select play button(notify()) it wont play, ie wait() called by current song.

In this both cases songs going to Wait states.


Wait() and sleep() Differences?

Thread.sleep() Once its work completed then only its release the lock to everyone. until its never release the lock to anyone.

  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() When its going to waiting stage, its will be release the key and its waiting for some of the seconds based on the parameter.

For Example:

you are take the coffee in yours right hand, you can take another anyone of the same hand, when will your put down then only take another object same type here. also. this is sleep() you sleep time you didn't any work, you are doing only sleeping.. same here also.

wait(). when you are put down and take another one mean while you are waiting , that's wait

you are play movie or anything in yours system same as player you can't play more than one at a time right, thats its here, when you close and choose another anyone movie or song mean while is called wait





java-threads