CyclicBarrier

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 5 min

TL;DR

  • CyclicBarrier is a synchronization aid that allows a fixed number of threads to all wait for each other to reach a common barrier point.
  • It is exactly like a CountDownLatch, except it can be reused (cyclic) after the barrier is broken.
  • You can optionally provide a Runnable action that executes the moment the barrier is breached (before the threads are released).

Concept

Imagine 4 friends taking a road trip in 4 separate cars. They agree to meet at a specific gas station before crossing the state border.
Friend 1 arrives and waits. Friend 2 arrives and waits.
When the 4th friend finally arrives, the barrier is broken. They can optionally perform a group action (like “Take a group selfie”), and then all 4 cars are instantly allowed to continue driving.

Because it is “Cyclic”, they can agree to meet again at a restaurant 100 miles later using the exact same CyclicBarrier object.

Examples

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {
    public static void main(String[] args) {
        
        // Wait for 3 threads. When all 3 arrive, execute the Runnable.
        CyclicBarrier barrier = new CyclicBarrier(3, () -> {
            System.out.println("BARRIER BROKEN! All threads arrived. Resetting for next phase...");
        });
        
        Runnable task = () -> {
            try {
                System.out.println(Thread.currentThread().getName() + " doing Phase 1...");
                Thread.sleep((long)(Math.random() * 1000));
                
                System.out.println(Thread.currentThread().getName() + " reached barrier.");
                barrier.await(); // Blocks until all 3 threads reach here
                
                System.out.println(Thread.currentThread().getName() + " doing Phase 2...");
                
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        };
        
        new Thread(task, "Thread-A").start();
        new Thread(task, "Thread-B").start();
        new Thread(task, "Thread-C").start();
    }
}

Interview Questions

Q: What is the primary difference between CountDownLatch and CyclicBarrier?
A: 1. Reusability: A CountDownLatch cannot be reset once it hits 0. A CyclicBarrier automatically resets to its original value after the barrier is broken.
2. Action: A CyclicBarrier can execute a specific Runnable task exactly when the barrier is tripped, before the waiting threads are released. CountDownLatch does not have this feature.
3. Roles: In a Latch, usually 1 thread waits for N threads to finish. In a Barrier, N threads wait for each other.

Q: What is a BrokenBarrierException?
A: If three threads are waiting at a CyclicBarrier, and one of those threads gets interrupted (via Thread.interrupt()) or times out, the barrier is considered “broken”. The barrier throws a BrokenBarrierException to all the other threads currently waiting, forcefully waking them up and aborting the sync point, because the required number of threads can no longer be reached.