O wait() não funciona

7 respostas
G

Olá amigos, estou tendo problemas ao usar o wait(). Ele simplesmente não funciona. No código abaixo por exemplo, a thread deveria ficar paralizada quando executasse o wait() e, só retomar sua execução quando outro thread executasse o notifyAll(), mas a sua execução continua e ela imprime na saída padrão a string “oi”.

public class Teste
{
  public static void main( String argumentos[] )
  {
    new PrimeThread().start();
  }
}
     
class PrimeThread extends Thread
{
  public void run()
  {
    try { wait(); } catch (Exception ex){}
    System.out.println("oi");
  }
}

O que está acontecendo? Por que o wait() não funciona?

Agradeço a quem puder me ajudar. =)

7 Respostas

E

O wait gerou a seguinte exceção, ao ser executado:

IllegalMonitorStateException

Só que você engoliu a exceção. E então dá a impressão que ele passou batido pelo wait, quando na verdade ele gerou uma exceção.

Dica: engolir exceções é muito feio. Eu ia dar um exemplo que costumo dar quando explico a alguém sobre como é feio engolir exceções, mas desconfio que é um pouco pornográfico demais para postar aqui.

Veja:

http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#wait()

Dica: não use o “wait” da classe Thread para fazer ela esperar por alguma coisa. Crie um objeto vazio (da classe Object mesmo), e use-o para efetuar a sua sincronização.

ViniGodoy

Métodos como wait() e notify() só funcionam dentro de código sincronizado.

E

Uma coisa misteriosa e insondável para mim é o fato de a classe Object ter métodos “wait” e “notify”.
Eu acho que tais métodos não deveriam estar lá; deveriam estar disponíveis apenas se a classe implementasse uma interface (digamos “Waitable” ou “Synchronizable”). Assim como o “catch” aceita apenas classes que implementam Throwable, o “synchronized” deveria apenas aceitar classes que implementam Synchronizable.

G

Acho que entendi agora. Mas esses métodos devem ser definidos em outro objeto, ou podem ser usados no objeto atual? Ex:

obj.wait() ou wait() (equivalente a this.wait())

Desde já agradeço.

ViniGodoy
entanglement:
Uma coisa misteriosa e insondável para mim é o fato de a classe Object ter métodos "wait" e "notify". Eu acho que tais métodos não deveriam estar lá; deveriam estar disponíveis apenas se a classe implementasse uma interface (digamos "Waitable" ou "Synchronizable"). Assim como o "catch" aceita apenas classes que implementam Throwable, o "synchronized" deveria apenas aceitar classes que implementam Synchronizable.

Eu acharia melhor ainda se só existissem numa classe Lock. Mas, diferente da java.util.synchronized, funcionasse de maneira protegida, dentro de um bloco synchronized (sem a necessidade daqueles try...finally horrendos).

Algo como se faz hoje, mas só com um objeto específico:

private Lock lock = new Lock();

synchronized (lock) {
   while(<condicao>)
       lock.wait();
}
ViniGodoy
gabrielost:
ViniGodoy:
Métodos como wait() e notify() só funcionam dentro de código sincronizado.

Acho que entendi agora. Mas esses métodos devem ser definidos em outro objeto, ou podem ser usados no objeto atual? Ex:

obj.wait() ou wait() (equivalente a this.wait())

Desde já agradeço.

Tanto faz. O importante é que o mesmo objeto que foi usado dentro do synchronized seja usado para dar o wait, e depois para dar o notify.

Caso você só especifique o método como synchronized, esse objeto é o this.

Então:

public void umMetodo() {
    synchronized (this) {
       wait(); //Ok, pq é equivalente a this.wait();
    }
}
É equivalente a:
public synchronized void umMetodo() {
   wait(); //Ok, pq é equivalente a this.wait();
}

Se você sincronizar assim, aí vc tem que fazer o wait sobre outro objeto:

public class UmaClasse {
   private int[] x = new int[0]; //Um objeto qualquer

   public synchronized void umMetodo() {
      synchronized(x) {
         x.wait(); //Como o synchronized é sobre x, deve ser x.wait();
                      //E só vai acordar se o notify for dado sobre x
      }
   }  
}
G

ViniGodoy e entanglement, obrigado pelas esclarecimentos… =) Acho que estou conseguindo fazer aqui. xD

Criado 22 de outubro de 2010
Ultima resposta 22 de out. de 2010
Respostas 7
Participantes 3