Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java Phaser: deregister workers so a phase can complete

Last updated: 29 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A Phaser coordinates a registered set of participants across numbered phases and permits participants to deregister.

Download Java source kit

This complete program targets Java 8. Its displayed output is checked by the tutorial validation script.

Registration is a completion obligation

An import coordinator registers itself and two workers. Every registered party must arrive before the phase advances. A failed worker that leaves without arriving can keep the coordinator waiting forever. The fixture puts arrival and deregistration in finally so its registration is released even if work throws.

Register before starting the worker. Registering inside a thread can race with the coordinator arriving and advancing before the intended participant exists. The initial party count makes this fixture’s starting boundary explicit.

A barrier is not an error report

The workers increment a thread-safe completed counter. The barrier says both released their phase obligations; it does not say their business operations succeeded. Keep failures separately and inspect them after the phase when the task contract requires all records to pass.

This program waits without a timeout because its workers do bounded local work. Production coordination needs an interruption or deadline policy and a way to stop remaining tasks. Cancellation does not automatically roll back effects already committed by another worker.

Working program

Java
import java.util.concurrent.Phaser;
import java.util.concurrent.atomic.AtomicInteger;
public class ImportPhaseCompletion {
    public static void main(String[] args) throws Exception {
        Phaser phase = new Phaser(3);
        AtomicInteger completed = new AtomicInteger();
        Runnable task = () -> { try { completed.incrementAndGet(); } finally { phase.arriveAndDeregister(); } };
        Thread first = new Thread(task), second = new Thread(task);
        first.start(); second.start();
        phase.arriveAndAwaitAdvance();
        first.join(); second.join();
        System.out.println("completed=" + completed.get());
        System.out.println("remaining=" + phase.getRegisteredParties());
        phase.arriveAndDeregister();
        System.out.println("terminated=" + phase.isTerminated());
    }
}

Output

Output
completed=2
remaining=1
terminated=true

Costs and boundaries

The coordinator stores participant counts rather than one result per participant. This fixture creates two threads and one counter. A barrier does not bound task duration, and retaining worker results or failures adds application storage proportional to the worker count.

Common Mistakes

  • Release registration in finally when a worker exits.
  • Register before work can race with phase advancement.
  • Do not interpret arrival as business success.

Read next

Java threads: visibility, atomicity, and shared counters, Java cancellation: timed waits and cooperative interruption, Spring task executors: capacity, rejection and lost context.

Extend the tested workflow

Continue with Java CountDownLatch: completion counting does not count successful work.

java
phaser-registration
Storage details