Uma forma de encarar as threads é como se fossem pessoas que compartilham a mesma casa.
Se você passa uma tarefa a 5 threads, normalmente você quer que todas executem no tempo mais rápido possível, como se fossem corredores em uma corrida de 100 metros. A ordem de chegada dos corredores normalmente não pode ser prevista, se todos os corredores tiverem o mesmo nível técnico.
Se quiser que uma chegue depois da outra, ou você põe todo mundo em fila (como se fosse uma parada militar), ou então dá tarefas muito distintas e com tempo de execução muito diferente entre elas.
Ou então você faz algo do tipo “quando uma chegar, avisa a próxima”. Assim você terá uma pessoa chegando depois da outra, já que a pessoa só começa a correr depois que a outra já chegou.
O que você provavelmente quer é algo como “quando uma chegar, avisa a próxima”, o que é um exercício didático mas não é algo que se use na prática. Tente rodar o exemplo abaixo, e me explique porque é que às vezes esse exemplo fica “travado”. Corrija o erro do meu exemplo. (E veja por que é difícil, na verdade, trabalhar com “wait” e “notify”.
package guj;
public class ExemploRodarThreadsEmSequencia {
static class MinhaThread implements Runnable {
public MinhaThread (Thread outraThread) { this.outraThread = outraThread;}
public void run() {
System.out.printf ("Thread %s iniciou...%n", Thread.currentThread().getName());
if (outraThread != null) {
System.out.printf ("Thread %s espera thread %s%n", Thread.currentThread().getName(), outraThread.getName());
synchronized (outraThread) {
try {
outraThread.wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
System.out.printf ("Thread %s finalizou...%n", Thread.currentThread().getName());
synchronized (this) {
this.notify();
}
}
/** A outra thread que esta thread tem de esperar... */
private Thread outraThread;
}
public void teste() throws InterruptedException {
Thread[] threads = new Thread[5];
threads[0] = new Thread(new MinhaThread (null), "Thread 0");
for (int i = 1; i < 5; ++i) {
threads[i] = new Thread (new MinhaThread (threads[i-1]), String.format ("Thread %d", i));
}
for (int i = 4; i >= 0; i--) {
threads[i].start();
}
for (int i = 0; i < 5; ++i) {
threads[i].join();
}
}
/**
* @param args
*/
public static void main(String[] args) throws InterruptedException {
ExemploRodarThreadsEmSequencia ertes = new ExemploRodarThreadsEmSequencia();
ertes.teste();
}
}
Dica: o que ocorre se uma das threads encerra antes de a thread que a está esperando começar a esperar por ela?