O que é synchronized e como utilizá-lo?

A palavra-chave synchronized em Java permite controlar o acesso de múltiplas threads a um recurso compartilhado, evitando Race Conditions.

O que é synchronized e como utilizá-lo?

O synchronized em Java é um mecanismo que garante que apenas uma thread por vez execute um determinado bloco de código ou método, evitando problemas de concorrência como Race Conditions.

1. Por que usar synchronized?

Quando múltiplas threads acessam um recurso compartilhado, elas podem modificar dados de forma inconsistente. O synchronized resolve isso garantindo exclusão mútua.

2. Usando synchronized em métodos

O uso mais comum de synchronized é aplicá-lo diretamente a um método:

class Contador {
    private int valor = 0;

    public synchronized void incrementar() {
        valor++;
    }

    public int getValor() {
        return valor;
    }
}

Explicação:

  • O método incrementar() agora só pode ser executado por uma thread por vez.

3. Usando synchronized em blocos de código

Podemos sincronizar apenas partes críticas do código:

class Contador {
    private int valor = 0;

    public void incrementar() {
        synchronized (this) {
            valor++;
        }
    }
}

Vantagem: Bloquear apenas a parte necessária melhora o desempenho da aplicação.

4. Sincronizando com objetos específicos

Podemos sincronizar usando um objeto como lock compartilhado:

class Contador {
    private int valor = 0;
    private final Object lock = new Object();

    public void incrementar() {
        synchronized (lock) {
            valor++;
        }
    }
}

Útil quando várias instâncias compartilham o mesmo bloqueio.

5. Problemas do synchronized

  • Deadlock: Se duas threads ficarem bloqueadas esperando uma ação da outra.
  • Baixo desempenho: Pode reduzir a escalabilidade em sistemas de alto desempenho.
  • Não funciona para operações atômicas: Para isso, prefira AtomicInteger.

Conclusão

O synchronized é uma ferramenta essencial para controle de concorrência em Java, garantindo a integridade dos dados ao impedir que múltiplas threads modifiquem um recurso ao mesmo tempo. No entanto, deve ser usado com cautela para evitar problemas de desempenho e deadlocks.

A sincronização é um dos desafios mais complexos na programação multithread. Em sistemas críticos, como bancos de dados e transações financeiras, garantir que apenas uma thread execute determinada operação evita falhas graves. O uso do synchronized é fundamental para resolver esses problemas, mas, para sistemas de alto desempenho, alternativas como ReentrantLock e AtomicInteger podem ser mais eficientes.

Algumas aplicações:

  • Garantir a integridade de dados em sistemas multithread
  • Evitar Race Conditions em operações críticas
  • Controle de acesso a recursos compartilhados
  • Sincronização de operações bancárias e transações financeiras

Dicas para quem está começando

  • Use synchronized apenas quando necessário para evitar impacto no desempenho
  • Prefira sincronizar blocos de código ao invés de métodos inteiros
  • Evite deadlocks garantindo que os bloqueios sejam liberados corretamente
  • Para variáveis compartilhadas, considere AtomicInteger como alternativa

Contribuições de Rodrigo Farias

Compartilhe este tutorial: O que é synchronized e como utilizá-lo

Compartilhe este tutorial

Continue aprendendo:

Como evitar Race Conditions em Java

Race Conditions ocorrem quando múltiplas threads acessam e modificam a mesma variável simultaneamente, causando resultados imprevisíveis.

Tutorial anterior

Como utilizar ReentrantLock para sincronização de threads

ReentrantLock é uma alternativa ao synchronized, oferecendo mais controle sobre o bloqueio de threads em Java.

Próximo tutorial