Quando você usa a palavra-chave sincronizada, um mutex é usado para garantir a segurança do thread e o acesso síncrono aos recursos compartilhados. Freqüentemente, é necessária uma execução coordenada adicional entre threads para concluir tarefas simultâneas complexas. Por exemplo, o modo de espera/notificação é um mecanismo de execução coordenada em um ambiente multithread.
Adquirir e liberar bloqueios por meio da API (usando um mutex) ou chamar wait/notify e outros métodos são todos métodos de chamada de baixo nível. Além disso, é necessário criar abstrações de nível superior para sincronização de threads. A classe auxiliar de sincronização comumente usada é encapsular ainda mais o mecanismo de atividade de sincronização entre dois ou mais threads. Seu princípio interno é alcançar uma coordenação complexa entre threads usando a API subjacente existente.
Existem 5 classes auxiliares de sincronização adequadas para cenários de sincronização comuns:
1. Semaphore Semaphore é uma ferramenta clássica de sincronização. Os semáforos são frequentemente usados para limitar o número de recursos (físicos ou lógicos) que um thread pode acessar simultaneamente.
2.CountDownLatch é uma classe auxiliar de sincronização muito simples, mas comumente usada. Seu objetivo é permitir que uma ou mais threads sejam bloqueadas até que um conjunto de operações executadas em outras threads seja concluído.
3. CyclicBarrier é um ponto de sincronização multidirecional reconfigurável que é útil em certos cenários de programação simultânea. Ele permite que um grupo de threads espere um pelo outro até que um ponto de barreira comum seja alcançado. CyclicBarrier é útil em programas que envolvem um conjunto de threads de tamanho fixo que devem esperar uns pelos outros de tempos em tempos. Como a barreira pode ser reutilizada após a liberação do thread em espera, ela é chamada de barreira cíclica.
4. Phaser é uma barreira de sincronização reutilizável com função semelhante a CyclicBarrier e CountDownLatch, mas com uso mais flexível. É muito adequado para coordenar de forma síncrona tarefas de computação em fases em um ambiente multithread (quando a sincronização é necessária entre subtarefas na estrutura Fork/Join, o Phaser é o preferido)
5.Exchanger permite que dois threads troquem objetos em um determinado ponto de encontro, o que é mais útil em determinados projetos de pipeline. O Exchanger fornece um ponto de sincronização no qual um par de threads pode trocar dados. Cada thread fornece dados ao seu thread parceiro por meio da entrada do método exchange() e recebe os dados fornecidos pelo seu thread parceiro e os retorna. Quando dois threads trocam objetos por meio do Exchanger, a troca é segura para ambos os threads. Exchanger pode ser considerado uma forma bidirecional de SynchronousQueue, que é mais útil em aplicações que envolvem algoritmos genéticos e design de pipeline.