O que significa IllegalMonitorStateException e como resolver esse erro?
O erro IllegalMonitorStateException ocorre em Java quando um thread tenta chamar wait(), notify() ou notifyAll() sem possuir o monitor do objeto. Esse problema acontece principalmente em blocos de código que tentam sincronizar objetos sem a palavra-chave synchronized.
Causas comuns do erro IllegalMonitorStateException
Chamar wait(), notify() ou notifyAll() fora de um bloco sincronizado.
Tentar manipular um objeto compartilhado sem usar synchronized.
Trabalhar com synchronized em um objeto errado.
Exemplo de erro e solução
Código que gera o erro:
public class Exemplo {
public static void main(String[] args) {
Object lock = new Object();
try {
lock.wait(); // Lançará IllegalMonitorStateException
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
O erro ocorre porque não estamos dentro de um bloco synchronized ao chamar wait().
Correção:
public class Exemplo {
public static void main(String[] args) {
Object lock = new Object();
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
A solução correta é garantir que wait(), notify() e notifyAll() sejam chamados dentro de um bloco synchronized.
Como evitar IllegalMonitorStateException?
Sempre chame wait(), notify() e notifyAll() dentro de um bloco synchronized.
Garanta que a thread que está chamando esses métodos possui o monitor do objeto.
Prefira utilizar classes como Lock e Condition para evitar erros de sincronização.
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
public class ExemploLock {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
lock.lock();
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
Conclusão
O erro IllegalMonitorStateException pode ser evitado garantindo que wait(), notify() e notifyAll() sejam chamados dentro de blocos synchronized. Alternativamente, utilizar Lock e Condition do pacote java.util.concurrent.locks pode oferecer um controle mais seguro sobre sincronização entre threads.
Boas práticas para evitar IllegalMonitorStateException em Java
IllegalMonitorStateException é um erro comum ao lidar com concorrência em Java. Ele ocorre quando tentamos manipular threads sem utilizar blocos synchronized corretamente. Esse problema pode ser evitado garantindo que as chamadas de wait(), notify() e notifyAll() sejam feitas dentro de seções sincronizadas e, em casos mais avançados, utilizando Lock e Condition para controle mais preciso.
Algumas aplicações:
- Garantir sincronização correta entre threads
- Evitar falhas ao utilizar wait() e notify()
- Melhorar a segurança e a estabilidade de aplicações concorrentes
- Facilitar o gerenciamento de locks e sincronização de processos
Dicas para quem está começando
- Sempre utilize wait() e notify() dentro de blocos synchronized
- Prefira usar Lock e Condition para evitar erros de sincronização
- Verifique se a thread possui o monitor do objeto antes de chamar wait()
- Evite chamar notify() em objetos que não estão sincronizados
Rodrigo Farias
Desenvolvedor Java focado em aplicações corporativas e microsserviços.
Mais sobre o autor