CyclicBarrier in Java

Use `CyclicBarrier` in Java when a fixed group of worker threads must repeatedly meet at the same phase boundary.

10.3.3.2 CyclicBarrier

Introduction

In the realm of Java concurrency, the CyclicBarrier is a powerful synchronization aid that enables a set of threads to wait for each other to reach a common barrier point. This is particularly useful in scenarios where multiple threads must perform tasks in phases, and each phase cannot proceed until all threads have completed the current phase. This section delves into the functionality, practical applications, and implementation of CyclicBarrier, providing a comprehensive understanding for experienced Java developers and software architects.

Understanding CyclicBarrier

Functionality

The CyclicBarrier class, part of the java.util.concurrent package, allows a fixed number of threads to wait for each other at a barrier point. Once all threads have reached this point, the barrier is broken, and the threads can proceed. Unlike CountDownLatch, which is a one-time use synchronizer, CyclicBarrier can be reused after the barrier is reached, making it ideal for iterative tasks.

Key Concepts

  • Barrier Action: An optional Runnable task that can be executed once all threads reach the barrier.
  • Reusability: After the barrier is tripped, it can be reset and reused, allowing for cyclic operations.
  • Parties: The number of threads that must reach the barrier before it is tripped.

Practical Application

Consider a scenario where multiple threads are performing complex calculations in phases. Each thread must complete its current phase before any can proceed to the next. CyclicBarrier ensures that all threads synchronize at the end of each phase, maintaining data consistency and coordination.

Example: Using CyclicBarrier

Let’s explore a practical example where multiple threads perform tasks and wait at a barrier before moving to the next phase.

 1import java.util.concurrent.BrokenBarrierException;
 2import java.util.concurrent.CyclicBarrier;
 3
 4public class CyclicBarrierExample {
 5
 6    private static final int NUMBER_OF_THREADS = 3;
 7    private static final CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_THREADS, new BarrierAction());
 8
 9    public static void main(String[] args) {
10        for (int i = 0; i < NUMBER_OF_THREADS; i++) {
11            new Thread(new Task(i)).start();
12        }
13    }
14
15    static class Task implements Runnable {
16        private final int id;
17
18        Task(int id) {
19            this.id = id;
20        }
21
22        @Override
23        public void run() {
24            try {
25                System.out.println("Thread " + id + " is performing task.");
26                Thread.sleep(1000); // Simulate task execution
27                System.out.println("Thread " + id + " waiting at barrier.");
28                barrier.await();
29                System.out.println("Thread " + id + " passed the barrier.");
30            } catch (InterruptedException | BrokenBarrierException e) {
31                e.printStackTrace();
32            }
33        }
34    }
35
36    static class BarrierAction implements Runnable {
37        @Override
38        public void run() {
39            System.out.println("All threads have reached the barrier. Barrier action executed.");
40        }
41    }
42}

Explanation

  • Task Execution: Each thread performs a task and waits at the barrier.
  • Barrier Action: Once all threads reach the barrier, the BarrierAction is executed.
  • Reusability: The barrier can be reused for subsequent phases.

Reusability of CyclicBarrier

A significant advantage of CyclicBarrier is its ability to be reused. After all threads have reached the barrier and the barrier action is executed, the barrier is reset, allowing threads to synchronize again in future iterations. This makes CyclicBarrier ideal for iterative algorithms and simulations.

Differences from CountDownLatch

While both CyclicBarrier and CountDownLatch are used for synchronization, they serve different purposes:

  • Reusability: CyclicBarrier can be reused after the barrier is tripped, whereas CountDownLatch cannot.
  • Barrier Action: CyclicBarrier supports an optional barrier action, executed once all threads reach the barrier.
  • Use Case: CyclicBarrier is suitable for scenarios requiring repeated synchronization, while CountDownLatch is ideal for one-time events.

Best Practices

  • Exception Handling: Always handle InterruptedException and BrokenBarrierException to ensure robust thread execution.
  • Thread Count: Ensure the number of threads matches the number of parties specified in the CyclicBarrier.
  • Barrier Action: Utilize the barrier action for tasks that should execute once all threads reach the barrier.

Common Pitfalls

  • Deadlock: Ensure all threads reach the barrier to avoid deadlock situations.
  • Thread Interruption: Handle thread interruptions gracefully to prevent unexpected behavior.
  • Resource Management: Manage resources efficiently to avoid bottlenecks when threads are waiting at the barrier.

Conclusion

The CyclicBarrier is a versatile and powerful tool in Java concurrency, enabling efficient synchronization of threads in iterative tasks. By understanding its functionality, practical applications, and differences from other synchronizers, developers can leverage CyclicBarrier to enhance the performance and reliability of multithreaded applications.

Further Reading

For more information on Java concurrency and synchronization, refer to the Oracle Java Documentation and explore related sections in this guide, such as 10.3.3.1 CountDownLatch.


Test Your Knowledge: CyclicBarrier in Java Concurrency Quiz

Loading quiz…

Revised on Thursday, April 23, 2026