Code Pumpkin

CyclicBarrier | Java Concurrency Utilities

May 25, 2017
Posted by Pumpkin
Subscribe

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.

CyclicBarrier

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:

  1. InterruptedException – if the current thread was interrupted while waiting
  2. 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 via BrokenBarrierException 

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 about Cyclic Barrier. Happy Learning smiley

Tags: , , , , ,


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.

Total Post : 80
Subscribe
Contribute Your Articles

Interview Experiences

Related Books

Like Us On Facebook

Alexa Page Rank