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”.
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.
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
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.
G
gabrielost
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:
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:
publicvoidumMetodo(){
synchronized(this){
wait(); //Ok, pq é equivalente a this.wait();}
}
É equivalente a:
publicsynchronizedvoidumMetodo(){
wait(); //Ok, pq é equivalente a this.wait();
}
Se você sincronizar assim, aí vc tem que fazer o wait sobre outro objeto:
publicclassUmaClasse{privateint[]x=newint[0];//Um objeto qualquerpublicsynchronizedvoidumMetodo(){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
gabrielost
ViniGodoy e entanglement, obrigado pelas esclarecimentos… =) Acho que estou conseguindo fazer aqui. xD