Différence entre attendre et dormir en Java

1. Vue d'ensemble

Dans ce court article, nous examinerons les méthodes standard sleep () et wait () du noyau Java, et nous comprendrons les différences et les similitudes entre elles.

2. Différences générales entre attendre et dormir

En termes simples, wait () est une méthode d'instance utilisée pour la synchronisation des threads.

Il peut être appelé sur n'importe quel objet, tel qu'il est défini directement sur java.lang.Object, mais il ne peut être appelé qu'à partir d'un bloc synchronisé . Il libère le verrou sur l'objet afin qu'un autre thread puisse intervenir et acquérir un verrou.

D'autre part, Thread.sleep () est une méthode statique qui peut être appelée à partir de n'importe quel contexte. Thread.sleep () met en pause le thread actuel et ne libère aucun verrou.

Voici un premier aperçu très simpliste de ces deux API principales en action:

private static Object LOCK = new Object(); private static void sleepWaitExamples() throws InterruptedException { Thread.sleep(1000); System.out.println( "Thread '" + Thread.currentThread().getName() + "' is woken after sleeping for 1 second"); synchronized (LOCK) { LOCK.wait(1000); System.out.println("Object '" + LOCK + "' is woken after" + " waiting for 1 second"); } } 

L'exécution de cet exemple produira la sortie suivante:

Le fil `` principal '' est réveillé après avoir dormi pendant 1 seconde

L'objet «[email protected]» est réveillé après avoir attendu 1 seconde

3. Réveil Attendez et dormez

Lorsque nous utilisons la méthode sleep () , un thread démarre après un intervalle de temps spécifié, à moins qu'il ne soit interrompu.

Pour wait () , le processus de réveil est un peu plus compliqué. Nous pouvons réveiller le thread en appelant les méthodes notify () ou notifyAll () sur le moniteur en attente.

Utilisez notifyAll () au lieu de notify () lorsque vous souhaitez réveiller tous les threads en attente. De la même manière que la méthode wait () elle-même, notify () et notifyAll () doivent être appelés à partir du contexte synchronisé.

Par exemple, voici comment vous pouvez attendre :

synchronized (b) { while (b.sum == 0) { System.out.println("Waiting for ThreadB to complete..."); b.wait(); } System.out.println("ThreadB has completed. " + "Sum from that thread is: " + b.sum); }

Et puis, voici comment un autre thread peut ensuite réveiller le thread en attente - en appelant notify () sur le moniteur :

int sum; @Override public void run() { synchronized (this) { int i = 0; while (i < 100000) { sum += i; i++; } notify(); } }

L'exécution de cet exemple produira la sortie suivante:

En attente de la fin de ThreadB…

ThreadB est terminé. La somme de ce fil est: 704982704

4. Conclusion

Ceci est une introduction rapide à la sémantique de l' attente et du sommeil en Java.

En général, nous devrions utiliser sleep () pour contrôler le temps d'exécution d'un thread et wait () pour la synchronisation multi-thread. Naturellement, il y a beaucoup plus à explorer - après avoir bien compris les bases.

Comme toujours, vous pouvez consulter les exemples fournis dans cet article sur GitHub.