What problem does Phaser solve that CyclicBarrier and Cou… — Cracked Java
// Concurrency & Multithreading · Synchronizers: Latch, Barrier, Semaphore, Phaser
SeniorTheory

What problem does Phaser solve that CyclicBarrier and CountDownLatch do not?

Phaser solves the problem that both CountDownLatch and CyclicBarrier have a fixed number of parties decided at construction. A Phaser lets threads register and deregister dynamically across phases, so it fits computations where the number of participants changes between rounds — and it is reusable across an arbitrary number of phases without throwing it away like a latch.

The two gaps it fills

  • CountDownLatch is one-shot with a fixed count — no reuse, no changing the count.
  • CyclicBarrier is reusable but the number of parties is locked at construction — you cannot add or remove participants mid-run, and threads can't drop out cleanly.

A Phaser does both: dynamic membership and multiple phases.

How it works

A phaser tracks parties (registered participants) and a monotonically increasing phase number. Each party calls arriveAndAwaitAdvance() to signal arrival and block until all registered parties arrive; when the last one does, the phaser advances to the next phase and releases everyone.

  • register() / bulkRegister(n) — add parties, even mid-flight.
  • arrive() — signal arrival without blocking.
  • arriveAndAwaitAdvance() — arrive and wait for phase advance (the barrier behavior).
  • arriveAndDeregister() — arrive and permanently drop out, shrinking the party count.
  • Override onAdvance(phase, parties) to run a per-phase action and to return true when the phaser should terminate.
Phaser phaser = new Phaser(1); // register self as controller

for (Task t : tasks) {
    phaser.register();         // add a party dynamically
    new Thread(() -> {
        for (int p = 0; p < t.rounds(); p++) {
            t.runPhase(p);
            phaser.arriveAndAwaitAdvance(); // sync at each phase
        }
        phaser.arriveAndDeregister();       // leave when done
    }).start();
}
phaser.arriveAndDeregister();  // controller drops out -> may terminate
phase 0:  P1 P2 P3        -> all arrive -> advance
phase 1:  P1 P2 P3 P4     <- P4 registered
phase 2:  P1    P3 P4     <- P2 deregistered (arriveAndDeregister)
... terminates when parties drop to 0 or onAdvance returns true
Phaser: parties change between phases

Extra reach

Phasers also tier: a parent phaser with child phasers reduces contention for large party counts. And onAdvance returning true (or party count hitting zero) cleanly terminates the phaser, which a barrier has no equivalent for.

Mark your status