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
Contribuições de Rodrigo Farias