Olá!
Estou lendo a parte de threads do livro “Complete Java 2 Certification Study Guide” e em certa altura eles propõem um exercício para mostrar que a ordem de notify é aleatória (enunciado anexado no final do tópico).
A idéia básica era de criar 2 classes: a primeira (Rendezvous) possuiria um método sincronizado que simplesmente chamava o wait(); e a segunda (Waiter) seria uma derivada de Thread onde seu método run() chamaria aquele método da primeira.
Dessa forma vários threads Waiter ficariam aguardando o notify de uma única instância de Rendezvous.
Minha implementação ficou assim:
Main.java
[code]public class Main {
public static void main(String[] args) {
int waiters = args.length > 0 ? Integer.parseInt(args[0]) : 5;
Rendezvous rendez = new Rendezvous();
Thread[] threads = new Thread[waiters];
for(int i = 0; i < waiters; i++) {
threads[i] = new Waiter(rendez);
threads[i].start();
}
synchronized(rendez) {
rendez.notifyAll();
}
System.out.print("---Program terminated---");
}
}[/code]
Rendezvous.java
public class Rendezvous {
public synchronized void hurryUpAndWait() {
try {
wait();
} catch(InterruptedException e) { }
}
}
Waiter.java
[code]public class Waiter extends Thread {
private static int counter = 0;
private Rendezvous rendez;
private int sn;
public Waiter(Rendezvous rendez) {
this.rendez = rendez;
this.sn = counter++;
}
public void run() {
rendez.hurryUpAndWait();
System.out.printf("Thread #%d just got notified.\n", sn);
}
}[/code]
Problemas:
- Ao rodar o programa eu nunca recebia a mensagem “Thread #? just got notified” de todos os threads. Por exemplo:
— com 5 instâncias de Waiter, geralmente eu só recebia 3 mensagens - de #0, #1 e #2 - e muitas vezes nenhuma mensagem.
— com 3 instâncias de Waiter, eu recebia no máximo 1 mensagem (#1) e com ainda mais frequência nenhuma.
— com 10 instâncias, sempre variava entre 4 e 7 mensagens. - Ao final da execução, os Threads continuavam rodando, não deixando o programa terminar.
PS: Vale citar que na maioria das vezes os threads que não imprimiam a mensagem eram os primeiros, mas isso também variava.
Agradeço qualquer esclarecimento.
ANEXOS:
Enunciado do exercício:
[quote]Begin with a class called Rendezvous, which has a single method called hurryUpAndWait(). The
method increments a counter and then calls wait(). Does the method need to be synchronized?
Next create a class called Waiter, which extends Thread. Its constructor should take an argument
of type Rendezvous. Its run() method calls hurryUpAndWait() on the instance of Rendezvous and
then prints out a message to report that notification has happened. (Getting notified is the only
way to return from hurryUpAndWait().) Each instance of Waiter should have a unique serial number,
assigned at creation time and printed out after notification, so that you will be able to know
the order in which threads were notified.
Your main class should create one instance of Rendezvous and multiple instances of Waiter.
The number of Waiter instances should be specified on the command line. After each Waiter
is created, call its hurryUpAndWait() method. Eventually all the Waiter instances will be waiting
on the Rendezvous object. Then call notifyAll() on Rendezvous. Observe the order in which
threads report that they have been notified.[/quote]