Atualizado: 07/09/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Sincronização de Threads em Fases com Phaser em Java

A classe Phaser, parte do pacote java.util.concurrent, é um mecanismo de sincronização projetado para coordenar threads que precisam executar uma tarefa dividida em múltiplas fases. Pense nela como uma barreira de sincronização reutilizável e dinâmica: um grupo de threads chega à barreira, espera que todos os outros membros do grupo cheguem, e então todas são liberadas simultaneamente para iniciar a próxima fase.

Sua principal vantagem sobre outras barreiras, como CyclicBarrier, é a capacidade de alterar dinamicamente o número de participantes registrados.

Os construtores mais comuns são:

  • Phaser(): Cria um Phaser sem participantes registrados inicialmente.
  • Phaser(int parties): Cria um Phaser já registrando um número inicial de participantes (parties).

Os métodos essenciais para controlar o fluxo são:

  • int register(): Registra um novo participante no Phaser. O número de participantes necessários para avançar a fase aumenta em um.
  • int arriveAndAwaitAdvance(): O método mais comum. A thread que o invoca sinaliza que concluiu a fase atual e fica bloqueada até que todos os outros participantes registrados também cheguem a esta barreira.
  • int arrive(): Sinaliza a conclusão da fase, mas a thread não espera pelas outras e continua sua execução imediatamente.
  • int arriveAndDeregister(): Sinaliza a conclusão da fase final de um participante e o remove do registro. O número de participantes necessários para avançar as fases futuras diminui em um.
  • int getPhase(): Retorna o número da fase atual (a contagem começa em 0).

Exemplo Prático de Sincronização em Fases

Vamos criar um programa com três participantes: a thread main e duas threads trabalhadoras (PhaseThread). Juntas, elas executarão uma tarefa de 3 fases.

import java.util.concurrent.Phaser;

public class Program {

    public static void main(String[] args) {
        // Cria um Phaser com 1 participante inicial (a própria thread main)
        Phaser phaser = new Phaser(1);
        int currentPhase;

        // Cria e inicia as threads trabalhadoras
        new Thread(new WorkerThread(phaser, "Worker-1")).start();
        new Thread(new WorkerThread(phaser, "Worker-2")).start();

        // --- FASE 0 ---
        currentPhase = phaser.getPhase();
        System.out.println("Main: aguardando conclusão da fase " + currentPhase);
        phaser.arriveAndAwaitAdvance(); // Main chega e espera os outros
        System.out.println("--- Fase " + currentPhase + " concluída ---");

        // --- FASE 1 ---
        currentPhase = phaser.getPhase();
        System.out.println("Main: aguardando conclusão da fase " + currentPhase);
        phaser.arriveAndAwaitAdvance(); // Main chega e espera os outros
        System.out.println("--- Fase " + currentPhase + " concluída ---");

        // --- FASE 2 ---
        currentPhase = phaser.getPhase();
        System.out.println("Main: aguardando conclusão da fase " + currentPhase);
        phaser.arriveAndAwaitAdvance(); // Main chega e espera os outros
        System.out.println("--- Fase " + currentPhase + " concluída ---");

        // Desregistra a thread main, pois seu trabalho acabou
        phaser.arriveAndDeregister();

        if (phaser.isTerminated()) {
            System.out.println("O Phaser foi finalizado com sucesso.");
        }
    }
}

class WorkerThread implements Runnable {
    private Phaser phaser;
    private String name;

    WorkerThread(Phaser p, String n) {
        this.phaser = p;
        this.name = n;
        phaser.register(); // Registra esta nova thread como participante
    }

    public void run() {
        // --- FASE 0 ---
        System.out.println(name + " iniciando fase " + phaser.getPhase());
        phaser.arriveAndAwaitAdvance(); // Sinaliza conclusão da fase e espera

        // --- FASE 1 ---
        System.out.println(name + " iniciando fase " + phaser.getPhase());
        phaser.arriveAndAwaitAdvance(); // Sinaliza conclusão da fase e espera

        // --- FASE 2 ---
        System.out.println(name + " iniciando fase " + phaser.getPhase());
        phaser.arriveAndDeregister(); // Sinaliza conclusão final e se desregistra
    }
}

Neste exemplo, o Phaser é iniciado com 1 participante (a main thread). Cada WorkerThread se registra ao ser criada, elevando o total de participantes para 3.

Cada um dos três participantes, ao final de uma fase, invoca phaser.arriveAndAwaitAdvance(). Este método bloqueia a thread até que o último dos 3 participantes também o invoque. Quando isso acontece, a barreira é liberada, o número da fase é incrementado, e todas as threads são desbloqueadas para iniciar o trabalho da próxima fase.

A saída do programa demonstra claramente a sincronização em cada etapa:

Main: aguardando conclusão da fase 0
Worker-1 iniciando fase 0
Worker-2 iniciando fase 0
--- Fase 0 concluída ---
Main: aguardando conclusão da fase 1
Worker-2 iniciando fase 1
Worker-1 iniciando fase 1
--- Fase 1 concluída ---
Main: aguardando conclusão da fase 2
Worker-1 iniciando fase 2
Worker-2 iniciando fase 2
--- Fase 2 concluída ---
O Phaser foi finalizado com sucesso.

A ordem das mensagens "iniciando fase" dentro de uma mesma etapa pode variar, mas a mensagem "Fase X concluída" só é impressa após todos os participantes terem chegado à barreira daquela fase.

Resumo

  • O Phaser sincroniza um grupo de threads através de múltiplas fases de uma tarefa.
  • Funciona como uma barreira de sincronização reutilizável cujo número de participantes pode mudar dinamicamente.
  • O método register() adiciona um novo participante, enquanto arriveAndDeregister() remove um.
  • O método arriveAndAwaitAdvance() é o ponto de encontro onde as threads esperam umas pelas outras antes de avançar para a próxima fase.
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com