A CyclicBarrier is a reusable rendezvous point: a fixed number of threads each call await(), and none proceed until all of them have arrived — at which point the barrier "trips," optionally runs a barrier action, and resets itself for the next round. Unlike a latch, the same threads that wait are the ones released, and it can be used over and over.
Mechanics
You construct it with the number of parties and, optionally, a Runnable barrier action. Each thread calls await(), which blocks until the arrival count equals the number of parties. The last thread to arrive runs the barrier action (on that thread, before any waiter is released), then all parties are released together and the barrier resets.
await() returns the arrival index (parties − 1 down to 0), which is handy for assigning roles. It can be interrupted or time out.
int parties = 3;
CyclicBarrier barrier = new CyclicBarrier(parties,
() -> System.out.println("phase complete, merging results"));
Runnable worker = () -> {
for (int phase = 0; phase < 5; phase++) {
computePartOfPhase(phase);
try {
barrier.await(); // wait for the other two, then continue
} catch (InterruptedException | BrokenBarrierException e) {
Thread.currentThread().interrupt();
return;
}
}
};
How it differs from a latch
| Operation | Best | Average | Worst | Note |
|---|---|---|---|---|
| Resets? | CountDownLatch: no (one-shot) | CyclicBarrier: yes (cyclic) | barrier reuses across rounds | |
| Who waits | Latch: any threads wait for events | Barrier: the parties wait for each other | barrier releases the arrivers | |
| Built-in action | Latch: none | Barrier: optional Runnable on trip | runs on the last arriver | |
| Failure mode | Latch: just blocks | Barrier: BrokenBarrierException | one failure breaks all waiters |
The broken barrier
This is the trick part. If any waiting thread is interrupted, times out, or the barrier is reset() while threads wait, the barrier enters a broken state: every other waiter wakes with a BrokenBarrierException, and the barrier becomes unusable until reset. This all-or-nothing semantics is the point — partial progress through a synchronized phase is meaningless, so the barrier fails everyone together.