explicação sobre a Exception IllegalMonitorStateException

2 respostas
LuanMesquita

Olá Pessoal,

estava dando uma estudada no java, especificamente em Threads e
o java me gerou uma Exception:

Exception in thread Thread-0 java.lang.IllegalMonitorStateException

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:485)

at Threads.Teste3.run(Teste3.java:24)

at java.lang.Thread.run(Thread.java:662)

Conseguir resolver o problema pesquisando nos fóruns da vida. O problema era
que eu estava usando o método wait() dentro de um método que não tinha
a definição synchronized. Compreendo o que faz o synchronized, ele bloquea
a entrada de uma segunda Thread dentro de um método, só não compreendir por que usar
a definição synchronized em um método que utilizada wait() para acabar com o
problema de Exception IllegalMonitorStateException. Por que do synchronized? o que têm haver?
qual o motivo da necessidade do synchronized?

Se alguém souber me explicar, fico muito agradecido pois muitas pessoas
estão com essa dúvida más não estão obtendo explicações significativas.

Vlww Pessoal
Fuii

2 Respostas

C

Você já leu isto?
http://www.guj.com.br/articles/43

rmendes08

Quando um bloco de código synchronized chama o método wait() significa que ele deve esperar por uma notificação de alguma outra thread de que ele pode continuar com o seu trabalho. Essa notificação, obrigatoriamente tem de vir de alguma thread que disputa o objeto monitor desse bloco de código, se pudesse vir de qualquer outra thread a VM ficaria um caos, pois uma thread que não tem nada a ver com o trabalho desse bloco de código notificaria o bloco de que ele pode continuar com o seu trabalho quando na verdade ele não pode.

Por exemplo, imagine a implementação de um buffer, com métodos sincronizados para produzir e consumir objetos do buffer. O método produzir() somente escreve se houver espaço e o método consumir somente consome se não estiver vazio. Para obter esse efeito você precisaria de algo assim:

synchronized void produzir(){
   while( isBufferFull() ){
     wait();
   }

   criaObjetoNoBuffer();

   notifyAll();
}

synchronized void consumir(){
   while( isBufferEmpty() ){
     wait();
   }

  consomeObjetoDoBuffer();

  notifyAll();
}

Ou seja, o método produzir() espera até que o buffer não esteja cheio para criar um objeto, e então notifica as outras threads de que terminou o seu seriço. Isso deve ser feito pois pode existir uma thread executando o método consumir() esperando algum objeto a ser criado no buffer para continuar sua execução. Agora imagine a seguinte situação. Você tem 2 buffers A e B e 2 threads, uma executando o método produzir() sobre o buffer A e outra executando o método consumir() sobre o buffer B. A 1a thread executa até encher o buffer A enquanto a 2a thread tem que esperar alguém produzir algo no buffer B. Se não houvesse a restrição de uma thread notificar apenas threads do mesmo monitor, a 1a thread notificaria a 2a thread de que ela pode continuar sendo que ela não pode, pois não existe nada no buffer B ainda, ou seja, chega-se a uma inconsistência no estado dos objetos.

Criado 5 de março de 2011
Ultima resposta 7 de mar. de 2011
Respostas 2
Participantes 3