In Java’s concurrency utilities, CyclicBarrier is a synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. It is called “cyclic” because it can be re-used after the waiting threads are released.
Here is a breakdown of how to use it effectively.
1. Basic Concepts
- Parties: The number of threads that must invoke
await()before the barrier is tripped. - Barrier Action: An optional
Runnablethat is executed once per barrier point, after the last thread arrives, but before any threads are released. - await(): The core method threads call to wait. It blocks until all parties have arrived.
2. Implementation Steps
Create the Barrier
You initialize it with the number of participating threads.
import java.util.concurrent.CyclicBarrier;
// ...
int parties = 3;
CyclicBarrier barrier = new CyclicBarrier(parties, () -> {
// This runs once all threads reach the barrier
System.out.println("Barrier reached! Processing combined results...");
});
Define the Worker
Each thread performs its task and then calls barrier.await().
package org.kodejava.util.concurrent;
import java.util.concurrent.CyclicBarrier;
class Task implements Runnable {
private final CyclicBarrier barrier;
Task(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " is working...");
// Simulate work
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " waiting at barrier.");
barrier.await(); // Thread blocks here
System.out.println(Thread.currentThread().getName() + " passed the barrier!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
3. Key Differences from CountDownLatch
While both coordinate threads, they have distinct use cases:
- Reusability: A
CyclicBarriercan be reset and used again (hence “cyclic”). ACountDownLatchcount cannot be reset once it reaches zero. - Waiting Mechanism: In a
CyclicBarrier, the workers wait for each other. In aCountDownLatch, a main thread typically waits for workers to finish (workers don’t necessarily block). - Barrier Action:
CyclicBarriersupports a custom action when the barrier trips;CountDownLatchdoes not.
4. Handling Broken Barriers
If a thread leaves the barrier prematurely (due to interruption, timeout, or failure), the barrier is considered “broken.” Any other threads waiting at the barrier will receive a BrokenBarrierException. You can check this status using barrier.isBroken().
Example Use Case
CyclicBarrier is ideal for parallel algorithms that involve multiple phases (iterative methods), where each phase must be completed by all threads before anyone starts the next phase.
