Depois de executar wait (), quanto tempo um thread espera se não for notificado de outros threads?
No exemplo abaixo, como o thread principal não está sendo notificado do thread filho, ele deve esperar para sempre. Mas o thread principal está sendo executado e a saída do exemplo abaixo é:
c
l
total: 19900
Por que o thread principal está sendo executado?
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);
}
}
Respostas
Resposta ao corpo da pergunta
Confira Thread#join(long):
[...] Quando um thread termina, o
this.notifyAll
método é invocado. [...]
Observe que Thread#join()
chama essa função com 0
, o que significa para sempre.
[...] Um tempo limite de 0 significa esperar para sempre.
Portanto, no seu caso aqui t
apenas chama notifyAll
quando termina, o que notifica o thread principal que está esperando t
.
Esse comportamento não intuitivo é a razão pela qual eles escrevem o seguinte na documentação:
Recomenda-se que os aplicativos não usar
wait
,notify
ounotifyAll
emThread
instâncias.
Resposta ao título da pergunta
Verifique Object#wait(ou JLS (17.2.1. Aguarde) ):
Um thread pode ser ativado sem ser notificado, interrompido ou expirar, uma chamada ativação espúria. Embora isso raramente ocorra na prática, os aplicativos devem se proteger testando a condição que deveria ter feito o thread ser ativado e continuando a esperar se a condição não for satisfeita.
Portanto, os threads em Java podem ser ativados a qualquer momento. Um despertar espúrio não é muito provável, mas pode acontecer.