Os métodos
wait(),
notify() e
notifyAll() só podem ser chamados no interior de um bloco ou método sincronizado, pois uma thread não pode notificar ou se colocar no modo de espera a não ser que ela possua a chave do objeto. Esses métodos geralmente são usados para a comunicação entre threads que se relacionam em um sistema de produtor e consumidor. O thread produtor usa
notify() ou
notifyAll() para comunicar à thread consumidora que o produto já está disponível para consumo, enquanto a thread consumidora usa o método
wait() para esperar que um produto fique disponível. Abaixo segue um exemplo de um relacionamento entre Threads nesse sistema de produtor e consumidor.
public class Produtor implements Runnable{
int num;
boolean peguei;
public Produtor(){
peguei=false;
}
public void run(){
while (true){
synchronized(this){
if (peguei){
peguei=false;
setNum();
notifyAll();
}
}
}
}
public synchronized int getNum(){
return num;
}
public synchronized void setNum(){
num = (int)(100*Math.random());
}
public boolean getPeguei(){
return peguei;
}
public void setPeguei(boolean p){
peguei=p;
}
}
public class Consumidor implements Runnable{
Produtor produtor;
String name;
public Consumidor(Produtor p, String s){
setName(s);
produtor=p;
}
public void run(){
while(true)
synchronized (produtor){
if(!produtor.getPeguei()){
System.out.println(produtor.getNum()+": "+getName());
produtor.setPeguei(true);
}
else
try{
produtor.wait();
Thread.sleep(10);
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public static void main(String args[]){
Runnable produtor = new Produtor();
Runnable consumidor1 = new Consumidor((Produtor)produtor, "Lucy");
Thread t1 = new Thread(produtor);
Thread t2 = new Thread(consumidor1);
t1.start();
t2.start();
}
}