Après avoir exécuté wait (), combien de temps un thread attend-il s'il n'est pas notifié par les autres threads?
Dans l'exemple ci-dessous, comme le thread principal ne reçoit pas de notification du thread enfant, il doit attendre indéfiniment. Mais le thread principal est exécuté et la sortie de l'exemple ci-dessous est:
c
l
total: 19900
Pourquoi le thread principal est-il exécuté?
public class ThreadX extends Thread {
static int total = 0;
public void run() {
synchronized (this) {
for (int i = 0; i < 200; i++) {
total = total + i;
}
System.out.println("c");
}
}
public static void main(String[] args) throws InterruptedException {
ThreadX t = new ThreadX();
t.start();
synchronized (t) {
t.wait();
System.out.println("l");
}
System.out.println("total: " + total);
}
}
Réponses
Réponse à la question-corps
Découvrez Thread#join(long):
[...] Lorsqu'un thread se termine, la
this.notifyAll
méthode est appelée. [...]
Notez que cela Thread#join()
appelle cette fonction avec 0
, ce qui signifie pour toujours.
[...] Un timeout de 0 signifie attendre indéfiniment.
Donc, dans votre cas, il t
n'appelle ici que notifyAll
lorsqu'il se termine, ce qui notifie le thread principal qui attend t
.
Ce comportement peu intuitif est la raison pour laquelle ils écrivent ce qui suit dans la documentation:
Il est recommandé que les applications utilisent pas
wait
,notify
ounotifyAll
sur lesThread
instances.
Réponse à la question-titre
Départ Object#wait(ou JLS (17.2.1. Attendre) ):
Un thread peut se réveiller sans être notifié, interrompu ou expiré, ce que l'on appelle un faux réveil. Bien que cela se produise rarement dans la pratique, les applications doivent se prémunir contre cela en testant la condition qui aurait dû provoquer le réveil du thread, et en continuant à attendre si la condition n'est pas satisfaite.
Ainsi, les threads en Java peuvent se réveiller à tout moment. Un faux réveil n'est pas très probable, mais cela peut arriver.