Question

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

Si je comprends bien, un thread wait () est toujours en mode de fonctionnement et utilise des cycles de processeur, mais un sleep () ne consomme aucun cycle de processeur. correct?

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

Était-ce utile?

La solution

A wait peut être " réveillé " par un autre thread appelant notifiez sur le moniteur qui est attendu alors qu'un sleep ne peut pas. De même, wait (et notify ) doit se produire dans un bloc synchronisé sur l'objet de contrôle, 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 thread peut faire

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

(sur le même objet mon ) et le premier thread (en supposant qu'il s'agisse du seul thread en attente sur le moniteur) se réactiveront.

Vous pouvez également appeler notifyAll si plusieurs threads attendent sur le moniteur & # 8211; cela les réveillera tous . Cependant, seul l'un des threads sera capable de récupérer le moniteur (rappelez-vous que le wait est dans un bloc synchronisé ) et continue & # 8211; les autres seront alors bloqués jusqu'à ce qu'ils puissent obtenir le verrou du moniteur.

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

Encore un autre point est que vous pouvez obtenir des réveils parasites à partir de wait (c’est-à-dire que le fil en attente reprend sans raison apparente). Vous devez toujours attendre lorsque vous faites tourner une condition comme suit:

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

Autres conseils

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

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


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

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

  

Tout finit par se retrouver dans le planificateur du système d'exploitation, qui   distribue des tranches de temps aux processus et aux threads.

     

sleep (n) dit que & # 8220; je & # 8217; ai terminé mon tranche de temps, et s'il vous plaît, ne me donnez pas   un autre pendant au moins n millisecondes. & # 8221; Le système d'exploitation n'essaie même pas de   planifiez le thread en veille jusqu'à ce que le temps demandé soit écoulé.

     

yield () dit que & # 8220; j'ai terminé mon tranche de temps, mais j'ai encore du travail à faire.   faire. & # 8221; Le système d’exploitation est libre de donner immédiatement au fil une autre tranche de temps,   ou pour donner un autre thread ou traiter le CPU le thread qui cède   vient d'abandonner.

     

wait () dit que & # 8220; je & # 8217; ai terminé avec mon tranche de temps. Ne me donnez pas un autre   couper le temps jusqu'à ce que quelqu'un appelle notify (). & # 8221; Comme avec sleep () , le système d'exploitation ne le sera pas & # 8217; t   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 fils perdent également le reste de leur tranche de temps lorsqu'ils exécutent   bloquant IO et dans quelques autres circonstances. Si un fil fonctionne   tout au long de la tranche horaire, le système d'exploitation prend le contrôle de force   si yield () a été appelé, afin que d'autres processus puissent s'exécuter.

     

Vous avez rarement besoin de yield () , mais si vous avez une application très lourde à calculer avec   limites logiques des tâches, l'insertion d'un yield () pourrait améliorer le système   réactivité (au détriment du temps, le contexte change, même juste   l’OS et retour, ne sont pas libres). Mesurer et tester contre vos objectifs   se soucient, comme toujours.

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

Cela ne concerne pas 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, pour 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éveillez-vous dans exactement 3,5 secondes) et / ou une équité codée en dur (laissez-vous dormir un moment 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 pourraient être implémentés de la même manière dans le système d’exploitation sous-jacent, voire pas du tout (car les versions précédentes de Java n’avaient pas de véritable multithreading; probablement de petites machines virtuelles ne le faisaient 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 sur laquelle il s'exécute.

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

wait ()

    La méthode
  1. 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 () lève InterruptedException {// ...}
  4. wait () doit être notifié par les méthodes notify () ou notifyAll () .
  5. La méthode
  6. wait () doit être appelée à partir d'une boucle afin de traiter les fausses alarmes.

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

sleep ()

    La méthode
  1. 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) lève InterruptedException {// ...}
  4. après le délai spécifié, sleep () est terminé.
  5. sleep () mieux de 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.

Réf.: 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    
}

 transition du thread vers différents états de thread

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 ():

Exemple 1 : utilisation de wait () et de veille ():

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

Laisse la clarté sur quelques notes clés:

  1. Appeler :
    • wait (): Appelle le thread en cours contenant l'objet HandObject
    • sleep (): la tâche d'exécution de l'appel sur thread est récupérée (sa méthode est donc affectée par le thread en cours)
  2. Synchronisé :
    • wait (): lorsqu’un multi-thread synchronisé accède au même objet (HandObject) (lorsqu’il est nécessaire de communiquer entre plusieurs threads (accès au thread exécuté, codage, exécution exécutée de la bière) accès au même objet HandObject)
    • sleep (): en attente de la condition d'exécution (attente disponible)
  3. Verrouillage :
    • wait (): libère le verrou pour qu'un autre objet ait une chance de s'exécuter (HandObject est gratuit, vous pouvez effectuer 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. État de réveil :
    • wait (): jusqu'à l'appel call notify (), notifyAll () depuis l'objet
    • sleep (): au moins jusqu'à l'expiration du délai ou l'interruption de l'appel
  5. Et le dernier point est utiliser lorsque , comme estani , indiquez:
  

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

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

Différence entre wait () et sleep ()

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

  • La principale différence est que wait () libère le verrou tandis que sleep () ne le libère pas 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, généralement.

  • wait () doit être appelé de l'intérieur de la synchronisation ou nous obtenons un IllegalMonitorStateException , tandis que sleep () peut être appelé n'importe où.

  • Pour redémarrer un fil à partir de wait () , vous devez appeler notify () ou notifyAll () . En ce qui concerne sleep (), , le thread est démarré après un intervalle de temps spécifié.

Similitudes

  • Les deux font que le fil de discussion actuel passe à l'état Non exécutable .
  • Les deux méthodes sont natives .

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

C’était juste 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 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 que vous souhaitez réactiver tous ces threads). Et vous avez besoin d'un verrou synchronisé ou d'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 entre threads, car si un thread passe en attente, vous aurez besoin d'un autre thread pour le réactiver.

Mais dans le cas de sleep () , il s'agit d'une méthode utilisée pour mettre le processus en attente 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 fréquemment posée dans les interviews: sleep () appartient à la classe Thread et wait () appartient à < code> Object class.

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

Et il existe une similitude entre les deux méthodes: elles sont toutes deux vérifiées, vous devez donc essayer catch ou throws pour accéder à ces méthodes.

J'espère que cela vous aidera.

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

  

Fil de discussion .sleep () envoie le thread actuel à l'état "Non exécutable" .   pendant 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é, aucun autre thread ne peut entrer dans ce bloc ou cette méthode. Si un autre fil appelle t.interrupt () , le thread en veille sera réveillé.

     

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 veille). UNE   L’erreur commune est d’appeler t.sleep () où t est un autre thread;   même dans ce cas, c’est le thread actuel qui dormira, pas le thread t.

     

t .suspend () est obsolète. En utilisant il est possible d'arrêter un thread autre   que le fil actuel. Un fil suspendu conserve tous ses moniteurs et   puisque cet état n'est pas interruptible, il est sujet aux blocages.

     

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

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.

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 en Java (à l'aide de surveiller ), mais sleep est une méthode simple de thread pour se mettre en pause.

sleep () est une méthode utilisée pour mettre le processus en attente pendant quelques secondes ou l'heure désirée, mais dans le cas d'une méthode wait (), le thread passe en état d'attente et a gagné & # 8217; t revenir automatiquement jusqu'à ce que nous appelons le notify () ou notifyAll ().

La différence majeure réside dans le fait 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 le sommeil est utilisé pour introduire la pause à l'exécution, en général.

Thread.sleep () envoie le fil de discussion actuel dans le fichier & # 8220; Non exécutable & # 8221; Etat pendant un certain temps. Le fil conserve les moniteurs acquis & # 8212; c'est-à-dire que 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 la mise en veille est une méthode statique, ce qui signifie qu'elle affecte toujours le thread en cours (celui qui exécute la méthode de mise en 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 dormira, pas le thread t.

object.wait () envoie le fil de discussion actuel dans le fichier & # 8220; Non exécutable & # 8221; état, comme dormir (), mais avec une torsion. Wait est appelé sur un objet, pas un thread; nous appelons cet objet l’objet & # 8220; verrouillé. & # 8221; Avant l'appel de 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 & # 8220; & # 8221; associé à la serrure. 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 principe, 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:

Appelez le:

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

Synchronisé:

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

Verrouillage de maintien:

  • wait (): libérez le verrou pour que d'autres objets puissent s'exécuter.
  • sleep (): maintenez le verrou enfoncé pendant au moins t fois si le délai d'expiration spécifié ou une interruption intervient.

Condition de réveil:

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

Utilisation:

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

Réf.: diff veille et wait

Les méthodes

wait et sleep sont très différentes:

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

En termes simples, attendez, attendez jusqu'à ce qu'un autre thread vous appelle, alors que sommeil est "n'exécute pas l'instruction suivante". pendant une certaine période de temps.

De plus, sleep est une méthode statique dans la classe Thread et fonctionne sur les threads, alors 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. :)

De cet article: http://javaconceptoftheday.com / différence-entre-méthodes-en-attente / java /

Méthode wait ().

1) Le thread qui appelle la méthode wait () libère le verrou qu'il 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 un verrou 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 threads en veille ne peuvent pas être réveillés par d'autres threads. Si cela est fait, le thread lèvera InterruptedException.

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

  1. wait () est une méthode de la classe Object .
    sleep () est une méthode de la classe Thread .

  2. sleep () permet au thread de passer à l'état sleep pendant x millisecondes.
    Lorsqu'un thread passe en état de veille , il ne libère pas le verrou .

  3. wait () permet au thread de relâcher le verrou et passe en état de suspension .
    Ce thread sera actif si une méthode notify () ou notifAll () est appelé pour le même objet.

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

La génération d'une exception lorsqu'elle 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.

Vous avez raison - Sleep () force le thread à "dormir". et le processeur s’éteindra et traitera d’autres threads (autrement appelé commutation de contexte), ce qui, je le crois, attend que le processeur traite 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, il existe en réalité un coût supplémentaire pour le changement de contexte: en fonction de la durée du sommeil, il peut être plus coûteux dans les cycles du processeur pour changer de thread que d’avoir simplement votre thread ne faisant rien pendant quelques ms.

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

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

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 notifié. Il est possible de spécifier le délai maximal d'attente: Object.wait (5000) afin qu'il soit possible d'utiliser wait pour, euh, dormir . mais alors vous devez vous embêter avec des serrures.

Aucune de ces méthodes n’utilise le processeur en veille / en attente.

Les méthodes sont implémentées à l'aide de code natif, à l'aide de constructions similaires mais pas de la même manière.

Cherchez 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 ...

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

Différences entre attente () et sommeil ()?

Thread.sleep ()      Une fois ses travaux terminés, il ne restaure que le verrou à tout le monde. jusqu'à ce qu'il ne lâche jamais le verrou à qui que ce soit.

  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 ()     Quand il sera en attente, il relâchera la touche 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. également. c'est le sommeil ()  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 tout ce qui se trouve dans votre système vous ne pouvez pas jouer plus d'un droit à la fois, c'est ici. Lorsque vous fermez et choisissez un autre film ou chanson, le terme attente est appelé

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

La méthode

sleep () amène le thread en cours à passer d'un état d'exécution à un état bloqué pendant une durée spécifiée. 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 blocage pendant un temps spécifié ou jusqu’à notification, mais dans ce cas le thread relâche le verrou de l’objet (ce qui signifie que d’autres threads peut exécuter toutes les méthodes synchronisées de l'objet appelant.

À 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 la communication entre les threads. Cela signifie que dormir / interrompre peut faire n'importe quoi, mais que 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. Il applique la synchronisation. Car le programmeur encapsule l'appel d'attendre / notifier dans un bloc synchronisé.

  3. Il est indépendant de l'origine et du nombre de threads. Cette approche vous permet d'ajouter arbitrairement d'autres threads sans modifier les autres threads ni en conserver la trace. Si vous avez utilisé veille / interruption, vous devez d’abord conserver les références aux threads en veille, puis les interrompre à la main.

Voici un exemple de la vie réelle qu'il est bon d'expliquer qu'il s'agit d'un restaurant classique et de la méthode utilisée par le personnel pour communiquer entre eux: les serveurs laissent les demandes des clients dans un lieu central (un tableau en liège, une table, etc.) .), sonne une cloche, et les ouvriers de la cuisine viennent 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 conduisent aux clients.

L'exemple relatif à la mise en veille ne libère pas le verrou et attend que

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 de singleton créées par threadA et threadB sont identiques. Cela signifie que threadB attend à l'extérieur jusqu'à ce que threadA relâche le verrou.

Modifiez maintenant le fichier 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 dans l'état "Non exécutable", threadB obtiendra la modification à entrer dans le bloc synchronisé.

Maintenant relancez:

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 au bout de 500 millisecondes, threadA a démarré à partir de sa dernière position et a créé un autre objet Singleton.

Doit être appelé depuis un bloc synchronisé: La méthode wait () est toujours appelée depuis un bloc synchronisé, c'est-à-dire que la méthode wait () doit verrouiller l'objet. surveiller avant objet sur lequel il est appelé. Cependant, 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 pas de moniteur d'objet.

IllegalMonitorStateException: si la méthode wait () est appelée sans acquérir le verrou d'objet, alors que IllegalMonitorStateException est levé à l'exécution, mais en veille ( ) par la méthode ne lève jamais une telle exception.

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

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

État du thread: lorsque la méthode wait () est appelée sur l'objet, le moniteur du thread qui était bloqué passe de l'état en attente à l'état attente et peut revenir à l'état exécutable. Etat 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 un thread, il passe de l'état d'exécution en attente à l'état d'attente et peut revenir à l'état d'exécution lorsque le temps de repos est écoulé.

Appelé à partir d'un bloc synchronisé: lorsque la méthode wait () est appelée, le thread laisse 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 de Référence

À partir de la page de documentation d'Oracle sur wait () méthode de Objet :

public final void wait()
  1. Force 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 du moniteur de cet objet de se réveiller
  3. les interruptions et les 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 d’Oracle sur sleep () méthode de la classe Thread :

public static void sleep(long millis)
  1. Met en veille (arrête temporairement l'exécution) le 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 moniteur.

Cette méthode jette:

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

  2. InterruptedException - si un thread a interrompu le thread actuel. 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).

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 < code> yield () libère le lock () .

wait avec une valeur de délai peut se réveiller une fois le délai écoulé ou notifier celui qui est le plus tôt (ou l’interrompre également), alors qu’un sommeil se réveille lorsque le délai est écoulé ou l’interrompre selon ce qui est le plus tôt. wait () sans valeur de délai d'attente attendra jusqu'à ce qu'il soit averti ou interrompu

  • La méthode wait (1000) provoque la mise en veille du thread actuel jusqu'à une seconde .
  • L'appel à sleep (1000) provoque la mise en veille du thread actuel pendant exactement 1 seconde .
    • De même, le thread en veille ne verrouille aucune ressource . Mais attendre le fil.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top