O que significa IllegalMonitorStateException e como resolver esse erro?

IllegalMonitorStateException ocorre quando um thread tenta chamar wait(), notify() ou notifyAll() sem possuir o monitor do objeto.

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.

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

Compartilhe este tutorial: O que significa IllegalMonitorStateException e como resolver esse erro

Compartilhe este tutorial

Continue aprendendo:

Como corrigir BindException: Address already in use ao rodar um servidor Java

BindException ocorre quando a porta que o servidor Java tenta usar já está em uso por outro processo.

Tutorial anterior

Como corrigir ReentrantLock causando IllegalMonitorStateException

IllegalMonitorStateException ocorre ao usar ReentrantLock sem adquirir o bloqueio corretamente antes de chamar métodos de sincronização.

Próximo tutorial