Defini uma thread Calculator que calcula uma somatória e disponibiliza o resultado através do método getTotal(). A thread Reader mantém uma referência a Calculator e envia para a saída padrão o resultado calculado.
Como minha intenção era de que o print só fosse feito após o cálculo, Reader invoca wait() antes de invocar getTotal(). Já Calculator chama notify() após o cálculo.
No método main, crio uma instância de Calculator e três instâncias de Reader. Segue abaixo o código:
public class Calculator extends Thread {
private int total;
public void run() {
for (int i = 0; i < 10; i++)
total += i;
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
notify();
}
}
public int getTotal() {
return total;
}
}
public class Reader extends Thread {
Calculator c;
public Reader(Calculator c) {
this.c = c;
}
public void run() {
synchronized (c) {
try {
String name = Thread.currentThread().getName();
System.out.println(name + " is waiting...");
c.wait();
System.out.println("(" + Thread.currentThread().getName() + ") total is: " + c.getTotal());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Calculator c = new Calculator();
new Reader(c).start();
new Reader(c).start();
new Reader(c).start();
c.start();
}
}
Agora a parte curiosa: como notify() só é invocado uma vez, no máximo uma instância de Reader seria desbloqueda. Entretanto, a saída apresentada pelo programa foi a seguinte:
Thread-1 is waiting…
Thread-2 is waiting…
Thread-3 is waiting…
(Thread-1) total is: 45
(Thread-2) total is: 45
(Thread-3) total is: 45
Mesmo comentando a linha onde notify() é invocado, a saída é a mesma.
Sem entender o que aconteceu, modifiquei a forma como a thread Calculator era iniciada, trocando c.start(); por new Thread©.start();. Com isso, a saída foi a que eu esperava de início:
Thread-1 is waiting…
Thread-2 is waiting…
Thread-3 is waiting…
(Thread-1) total is: 45
Como isso é possível ? Imaginava que o mecanismo de sincronização era independente da forma de criação das threads.
Grato