CyclicBarrier | Java Concurrency Utilities
CyclicBarrier was introduced in Java 5 along with other concurrent classes like CountDownLatch, ConcurrentHashMap, CopyOnWriteArrayList, BlockingQueue within java.util.Concurrent package.
There are scenarios in concurrent programming when you want set of threads to wait for each other at a common point until all threads in the set have reached that common point.
The java.util.concurrent.CyclicBarrier
class is a barrier that all threads must wait at, until all threads reach it, before any of the threads can continue.
The barrier is called cyclic because it can be re-used after the waiting threads are released.
You can implement the same functionality using wait() & Notify() mechanism but it requires lot of code and getting it write in first attempt is tricky, With CyclicBarrier it can be done in just few lines.
CyclicBarrier Exmaple in Java
Here is an easy example to remember its behavior: "4 bikers have started driving from Manali to Leh. As all of them are driving at different speed, they have decided some checkpoints in their route. After reaching to first checkpoint, everybody waits for others to reach that checkpoint. Once all 4 arrives, they will refill the petrol tanks and resume their rides and drive until their next checkpoint. "
In above example, bikers are worker threads or parties. checkpoint is barrier. Once all bikers reaches the checkpoint/barrier they will refill the petrol (barrierAction) and reset the barrier.
Lets implement above situation using CyclicBarrier. For better understanding of this Java program, please read steps mentioned next to the program.
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierDemo { public static void main(String args[]) { // creating CyclicBarrier (checkPoint) with // 4 parties (Bikers) threads that need to call await() final CyclicBarrier checkPoint = new CyclicBarrier(4, new Runnable(){ @Override public void run(){ //This task will be executed once all biker threads will reach barrier System.out.println("\nAll bikers have arrived to checkpoint. Lets refill the petrol\n"); } }); //starting each of thread Thread biker1 = new Thread(new Biker(checkPoint), "Biker Thread 1"); Thread biker2 = new Thread(new Biker(checkPoint), "Biker Thread 2"); Thread biker3 = new Thread(new Biker(checkPoint), "Biker Thread 3"); Thread biker4 = new Thread(new Biker(checkPoint), "Biker Thread 4"); biker1.start(); biker2.start(); biker3.start(); biker4.start(); } } class Biker implements Runnable { private CyclicBarrier checkPoint; public Biker(CyclicBarrier checkPoint) { this.checkPoint = checkPoint; } // Code to be executed by each biker @Override public void run() { try { System.out.println(Thread.currentThread().getName() + " has left Manali"); checkPoint.await(); System.out.println(Thread.currentThread().getName() + " has left the first checkpoint / barrier"); checkPoint.await(); System.out.println(Thread.currentThread().getName() + " has left the second checkpoint / barrier"); checkPoint.await(); System.out.println(Thread.currentThread().getName() + " has reached Leh"); } catch (InterruptedException | BrokenBarrierException ex) { ex.printStackTrace(); } } }
Output
Biker Thread 1 has left Manali Biker Thread 3 has left Manali Biker Thread 2 has left Manali Biker Thread 4 has left Manali All bikers have arrived to checkpoint. Lets refill the petrol Biker Thread 4 has left the first checkpoint / barrier Biker Thread 1 has left the first checkpoint / barrier Biker Thread 3 has left the first checkpoint / barrier Biker Thread 2 has left the first checkpoint / barrier All bikers have arrived to checkpoint. Lets refill the petrol Biker Thread 2 has left the second checkpoint / barrier Biker Thread 4 has left the second checkpoint / barrier Biker Thread 3 has left the second checkpoint / barrier Biker Thread 1 has left the second checkpoint / barrier All bikers have arrived to checkpoint. Lets refill the petrol Biker Thread 1 has reached Leh Biker Thread 2 has reached Leh Biker Thread 4 has reached Leh Biker Thread 3 has reached Leh
Steps To Use CyclicBarrier In Your Java Program
1. Start main thread
2. Create CyclicBarrier object
CyclicBarrier class has following two constructors. Both of them create a new CyclicBarrier object with the total number of parties / threads which wait for each other after reaching the Barrier.
CyclicBarrier(int parties); CyclicBarrier(int parties, Runnable barrierAction);
Here parties parameter signifies the number of threads that must invoke await()
after reaching the barrier i.e. Biker threads
barrierAction specifies a thread that will be executed when the barrier is reached i.e. Refilling Petrol
3. Create and start N threads
4. Call await() method at each barrier/checkpoint in thread's run() method.
When each thread reaches the barrier (checkpoint), call await()
method on the CyclicBarrier object. This will suspend the thread until all the thread also call the await()
method on the same CyclicBarrier object.
Once all the specified threads have called await()
method, they can resume operation.
await()
method has following two forms :
public int await() throws InterruptedException, BrokenBarrierException public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
In the second form, it waits until all parties have invoked await()
on this barrier, or the specified waiting time elapses.
await()
method returns int which is the arrival index of the current thread.
If the current thread is not the last to arrive then it is disabled for thread scheduling purposes and lies dormant until one of the following things happens:
- The last thread arrives; or
- The specified timeout elapses; (In case of second form) or
- Some other thread interrupts the current thread; or
- Some other thread interrupts one of the other waiting threads; or
- Some other thread times out while waiting for barrier; or
- Some other thread invokes reset() on this barrier.
await() method throws two exceptions:
-
InterruptedException
– if the current thread was interrupted while waiting -
BrokenBarrierException
If a thread leaves a barrier point prematurely because of interruption, failure, or timeout, all other threads waiting at that barrier point will also leave abnormally viaBrokenBarrierException
Though both CountDownLatch and CyclicBarrier are used as a synchronization aid that allows one or more threads to wait but there are certain differences between them that you should know. Here is our post CountDownLatch Vs CyclicBarrier | Java Concurrency Utilities where we have explained each difference in detail
That's all for this topic. If you guys have any suggestions or queries, feel free to drop a comment. We would be happy to add that in our post. You can also contribute your articles by creating contributor account here.
Happy Learning 🙂
If you like the content on CodePumpkin and if you wish to do something for the community and the planet Earth, you can donate to our campaign for planting more trees at CodePumpkin Cauvery Calling Campaign.
We may not get time to plant a tree, but we can definitely donate ₹42 per Tree.
About the Author
Tags: Concurrency, Core Java, Java, Multithreading, Synchronization, Thread
Comments and Queries
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:<pre><code class="java"> String foo = "bar"; </code></pre>For more information on supported HTML tags in disqus comment, click here.