Item 81: Prefira os utilitários de concorrência ao wait e notify

Motivação

Desde o Java 5, a plataforma oferece utilitários de concorrência de alto nível no pacote java.util.concurrent.
Eles substituem o uso manual e complexo de wait e notify.
São mais seguros e fáceis de usar, reduzindo a probabilidade de erros e…


This content originally appeared on DEV Community and was authored by Java Efetivo (livro)

Motivação

  • Desde o Java 5, a plataforma oferece utilitários de concorrência de alto nível no pacote java.util.concurrent.
  • Eles substituem o uso manual e complexo de wait e notify.
  • São mais seguros e fáceis de usar, reduzindo a probabilidade de erros em código concorrente.

Utilitários de Concorrência no java.util.concurrent
Categorias de utilitários:

  • Executor Framework: Gerenciamento de threads abordado no Item 80.
  • Coleções concorrentes: Implementações thread-safe de coleções padrão, como List, Queue e Map.
  • Sincronizadores: Coordenação entre threads, incluindo CountDownLatch, Semaphore, CyclicBarrier, Exchanger e Phaser.

Coleções Concorrentes

Características:

  • Internamente sincronizadas para alto desempenho.
  • Não permitem exclusão de atividade concorrente.
  • Operações atômicas como putIfAbsent aumentam a segurança e a usabilidade. Exemplo: Implementação de um Map thread-safe:
Map<String, String> map = new ConcurrentHashMap<>();
String result = map.putIfAbsent("key", "value");
if (result == null) {
    System.out.println("Valor inserido.");
} else {
    System.out.println("Chave já existente com valor: " + result);
}

Benefícios:

  • Substituem coleções sincronizadas (Collections.synchronizedMap).
  • Melhora significativa no desempenho de aplicações concorrentes.

Sincronizadores
Finalidade: Coordenação entre threads.

Exemplo de sincronizadores comuns:

  • CountDownLatch: Barreira de uso único para coordenação de threads.
  • Semaphore: Controle de acesso a recursos compartilhados.
  • CyclicBarrier: Sincronização em pontos de barreira reutilizáveis.
  • Phaser: Sincronização avançada e dinâmica de threads.

Exemplo Prático: Cronometragem Concorrente com CountDownLatch
Objetivo: Medir o tempo de execução de várias threads concorrentemente.

Implementação:

public static long time(Executor executor, int concurrency, Runnable action) throws InterruptedException {
    CountDownLatch ready = new CountDownLatch(concurrency);
    CountDownLatch start = new CountDownLatch(1);
    CountDownLatch done = new CountDownLatch(concurrency);

    for (int i = 0; i < concurrency; i++) {
        executor.execute(() -> {
            try {
                ready.countDown(); // Indica que está pronto
                start.await();     // Aguarda o sinal de início
                action.run();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                done.countDown(); // Indica que terminou
            }
        });
    }

    ready.await();   // Aguarda todas as threads ficarem prontas
    long startTime = System.nanoTime();
    start.countDown(); // Dispara o sinal de início
    done.await();     // Aguarda todas as threads finalizarem
    return System.nanoTime() - startTime;
}

Notas:

  • Usa três travas: ready (indica prontidão), start (disparo de início) e done (finalização).
  • Usa System.nanoTime para medir intervalos de tempo com precisão.

Prática Corrente com wait e notify
Apenas necessário para manutenção de código legado.
Regras principais:

  1. Sempre utilize um loop ao chamar wait:
synchronized (lock) {
    while (!condition) {
        lock.wait();
    }
}

  1. Teste a condição antes e depois da espera.
  2. Evite dependência de notify, prefira notifyAll.

Conclusão

  • Utilize os utilitários de concorrência sempre que possível.
  • Eles tornam o código mais legível, seguro e eficiente.
  • Alternativas modernas (como CyclicBarrier ou Phaser) podem substituir padrões baseados em wait e notify

Exemplos do livro

Image description

Image description

Image description

Image description


This content originally appeared on DEV Community and was authored by Java Efetivo (livro)


Print Share Comment Cite Upload Translate Updates
APA

Java Efetivo (livro) | Sciencx (2025-01-03T00:28:57+00:00) Item 81: Prefira os utilitários de concorrência ao wait e notify. Retrieved from https://www.scien.cx/2025/01/03/item-81-prefira-os-utilitarios-de-concorrencia-ao-wait-e-notify-2/

MLA
" » Item 81: Prefira os utilitários de concorrência ao wait e notify." Java Efetivo (livro) | Sciencx - Friday January 3, 2025, https://www.scien.cx/2025/01/03/item-81-prefira-os-utilitarios-de-concorrencia-ao-wait-e-notify-2/
HARVARD
Java Efetivo (livro) | Sciencx Friday January 3, 2025 » Item 81: Prefira os utilitários de concorrência ao wait e notify., viewed ,<https://www.scien.cx/2025/01/03/item-81-prefira-os-utilitarios-de-concorrencia-ao-wait-e-notify-2/>
VANCOUVER
Java Efetivo (livro) | Sciencx - » Item 81: Prefira os utilitários de concorrência ao wait e notify. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/01/03/item-81-prefira-os-utilitarios-de-concorrencia-ao-wait-e-notify-2/
CHICAGO
" » Item 81: Prefira os utilitários de concorrência ao wait e notify." Java Efetivo (livro) | Sciencx - Accessed . https://www.scien.cx/2025/01/03/item-81-prefira-os-utilitarios-de-concorrencia-ao-wait-e-notify-2/
IEEE
" » Item 81: Prefira os utilitários de concorrência ao wait e notify." Java Efetivo (livro) | Sciencx [Online]. Available: https://www.scien.cx/2025/01/03/item-81-prefira-os-utilitarios-de-concorrencia-ao-wait-e-notify-2/. [Accessed: ]
rf:citation
» Item 81: Prefira os utilitários de concorrência ao wait e notify | Java Efetivo (livro) | Sciencx | https://www.scien.cx/2025/01/03/item-81-prefira-os-utilitarios-de-concorrencia-ao-wait-e-notify-2/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.