Java

CyclicBarrier in Java

4 min read Updated Mar 21, 2026

Engineering Notes and Practical Examples

CyclicBarrier lets a fixed number of threads wait until all participants reach the same synchronization point.

Problem description:

We need multiple worker threads to finish one phase of work before any of them can safely move to the next phase.

What we are solving actually:

We are solving phased coordination, not mutual exclusion. The goal is to pause progress until all required workers reach the same checkpoint.

What we are doing actually:

  1. Create a barrier with the exact number of participating workers.
  2. Let each worker call await() after finishing the current phase.
  3. Release the whole group only when every worker has arrived.
sequenceDiagram
    participant W1 as Worker 1
    participant W2 as Worker 2
    participant W3 as Worker 3
    participant B as Barrier
    W1->>B: await()
    W2->>B: await()
    W3->>B: await()
    B-->>W1: release next phase
    B-->>W2: release next phase
    B-->>W3: release next phase

Real-World Use Cases

  • phased simulation systems
  • parallel data preparation before a final merge
  • batch processing pipelines with step boundaries

How It Works

  • create barrier with N parties
  • each worker calls await()
  • once all N arrive, optional barrier action runs
  • barrier can be reused for next cycle

Java 8 Example

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {
    public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(3, () ->
                System.out.println("All parties arrived. Merge step starts."));

        for (int i = 1; i <= 3; i++) {
            final int id = i;
            new Thread(() -> {
                try {
                    System.out.println("Worker " + id + " preparing data");
                    Thread.sleep(500L * id);
                    barrier.await();
                    System.out.println("Worker " + id + " continues next phase");
                } catch (Exception e) {
                    Thread.currentThread().interrupt();
                }
            }).start();
        }
    }
}

Multi-Phase Example Pattern

CyclicBarrier is most useful when the same group repeats phases.

for (int phase = 1; phase <= 3; phase++) {
    doPhaseWork(phase);
    barrier.await(); // all workers must finish current phase
}

This keeps phase boundaries explicit and deterministic.

Timeout and Broken Barrier Handling

One stuck worker can block everyone. Use timeout overload in real systems:

try {
    barrier.await(2, TimeUnit.SECONDS);
} catch (TimeoutException e) {
    // one participant was too slow
    barrier.reset();
} catch (BrokenBarrierException e) {
    // another participant failed or timed out
}

If one thread is interrupted while waiting, the barrier is broken and all waiting parties fail with BrokenBarrierException.

CyclicBarrier vs CountDownLatch vs Phaser

  • CountDownLatch: one-time wait; not reusable.
  • CyclicBarrier: reusable barrier with fixed participant count.
  • Phaser: dynamic participants and richer phase control.

Choose Phaser when parties can join/leave dynamically.

Operational Pitfalls

  1. Mismatch between configured parties and actual workers.
  2. Long-running or blocking barrier actions.
  3. Ignoring broken-barrier state after failures.
  4. No timeout policy, causing infinite waits.

Debug steps:

  • verify the configured party count matches the real number of workers
  • log when each thread reaches await() and when it resumes
  • use timeout-based await() in tests to catch stuck phases quickly
  • inspect broken-barrier handling after interruption or timeout

JDK 11 and Java 17 Notes

CyclicBarrier remains a stable and relevant choice in JDK 11 and Java 17 for repeated phase synchronization.

Java 21+ Guidance

For request-scoped parallel tasks, prefer StructuredTaskScope style orchestration over manual barriers when possible. Use CyclicBarrier when you explicitly need reusable phase synchronization.

Java 25 Note

No major usage change expected for CyclicBarrier; API is mature and stable.

Key Takeaways

  • CyclicBarrier is for reusable phase coordination.
  • Handle BrokenBarrierException and interruption correctly.
  • Use it only when all participants are known upfront.
  • Prefer timeout-based await in production workflows.

Categories

Tags

Comments