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
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.