Monday, July 19, 2021

Java CyclicBarrier Example for Beginners [Multithreading Tutorial]

This is the second part of my concurrency tutorial, in the first part, you have learned how to use CountDownLatch and in this part, you will learn how to use CyclicBarrier class in Java. CyclicBarrier is another concurrency utility introduced in Java 5 which is used when a number of threads (also known as parties) want to wait for each other at a common point, also known as the barrier before starting processing again. It's similar to CountDownLatch but instead of calling countDown() each thread calls await() and when the last thread calls await() which signals that it has reached the barrier, all threads started processing again, also known as a barrier is broken. 

You can use CyclicBarrier wherever you want to use CountDownLatch, but the opposite is not possible because you can not reuse the latch once the count reaches zero. Some of the common usages of CyclicBarrier is in writing a unit test for the concurrent program, to simulate concurrency in a test class, or calculating the final result after an individual task has been completed.

In this tutorial, I will show you an example of how four worker thread waits for others before starting again. As I told in the previous article, concurrency is hard to master, sometimes even if you read a couple of articles on one topic, you don't get what you are looking for. If you understand how and where to use CountDownLatch and CyclicBarrier, then only you will feel confident.

Books are also good for mastering concurrency, and one book, in particular, is very useful to learn multithreading and concurrency in Java. You guessed it right, I am talking about Java Concurrency in Practice by Brian Goetz, I strongly recommend this book to anyone who seriously wants to master threading and concurrency in Java. If you can't get first hand, get a second hand one, if you can't buy then lend it from the library but if you are serious about Java concurrency, you should read it.




CyclicBarrier Example in Java

You just cannot understand concurrency without an example, seeing is believing here. It's difficult to comprehend words like worker thread, parties, waiting for each other at a point, until you see it live in action. In this program, we have four worker threads and one main thread, which is running your main method. 

We have an object of CyclicBarrier, which is initialized with parties = 4, the argument we passed in the CyclicBarrier constructor is nothing but the number of parties, which is actually the number of threads to stop at the barrier. The barrier will not be broken until all parties have arrived. A party (thread) is said to have arrived with its call barrier.await() method.

In our example setup, we have given each worker thread a different name, starting from PARTY-1 to PARTY-4 just to have a meaningful output. We have passed the same instance of the cyclic barrier to each thread. If you look at their Runnable implementation, you will find that each party sleeps for some seconds and then call await() method on the barrier.

How to use CyclicBarrier in Java

The sleep is introduced so that every thread calls the barrier method after some time.  Sleep time is also in increasing order, which means PARTY-4 should be the last one to call await. So as per our theory, every thread (party) should wait after calling await() until the last thread (PARTY-4) calls the await() method, after that every thread should wake up and start processing.

Of course, they need to compete for CPU and they will start running once they got the CPU from the thread scheduler, but what is more important is that once the barrier is broken, each thread (party) becomes eligible for scheduling. By the way, you can reuse the barrier even after it's broken this is where CyclicBarrier is different than CountDownLatch.

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

/**
 * Java Program to demonstrate how to use CyclicBarrier, 
 * Its used when number of threads
 * needs to wait for each other before starting again.
 * 
 * @author Javin Paul
 */
public class HelloHP {

    public static void main(String args[]) throws InterruptedException,
                                                  BrokenBarrierException {
        
        CyclicBarrier barrier = new CyclicBarrier(4);
        Party first = new Party(1000, barrier, "PARTY-1");
        Party second = new Party(2000, barrier, "PARTY-2");
        Party third = new Party(3000, barrier, "PARTY-3");
        Party fourth = new Party(4000, barrier, "PARTY-4");
        
        first.start();
        second.start();
        third.start();
        fourth.start();
        
        System.out.println(Thread.currentThread().getName() + " has finished");

    }

}

class Party extends Thread {
    private int duration;
    private CyclicBarrier barrier;

    public Party(int duration, CyclicBarrier barrier, String name) {
        super(name);
        this.duration = duration;
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(duration);
            System.out.println(Thread.currentThread().getName() 
                                + " is calling await()");
            barrier.await();
            System.out.println(Thread.currentThread().getName() 
                                + " has started running again");
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

Output
main has finished
PARTY-1 is calling await()
PARTY-2 is calling await()
PARTY-3 is calling await()
PARTY-4 is calling await()
PARTY-4 has started running again
PARTY-1 has started running again
PARTY-2 has started running again
PARTY-3 has started running again

If you look at the output is exactly matches our theory. Each worker thread (PARTY 1 - 3) calls the await() method and then they stop processing until PARTY-4 comes and call await() method, after that every thread gets a wake-up call and started execution again, depending upon when they are scheduled by Java thread scheduler.

This is how CyclicBarrier class works. You can still reuse the barrier object and if a thread calls a barrier.await() again, it will wait for a four worker thread before it gets a wake-up call. By the way,  If the barrier is broken before a thread calls await() then this method will throw BrokenBarrierException. You can also see these free Java programming courses to learn essential Java concepts like these higher-level concurrency utilities in Java.



When to use CyclicBarrier in Java Program

It is a very useful class and has several practical uses. You can use this to perform the final task once individual tasks are completed. You can use it to write some unit tests to check some variants as well. Remember you can reuse the barrier as opposed to latching.  

On a side note, this CyclicBarrier example is also a good example of how to catch multiple exceptions in one catch block in Java, a feature introduced in JDK 1.7. You can see that we have two unrelated exceptions InterruptedException and BrokenBarrierException, but we have caught them in the same catch block, because of this feature, this code requires Java 7 to run. I

f you are not using JDK 7 then just use two catch blocks instead of one. You can also see these Java Concurrency courses to learn more about CountDownLatch, CyclicBarier, Phase, CompleteableFuture, and other concurrency utilities in Java. 

Java CyclicBarrier Example


That's all about how to use CyclicBarrier in Java. In this CyclicBarrier Example, you have not only learned how to use CyclicBarrier but also when to use it. You should use it when one thread needs to wait for a fixed number of threads before starting an event e.g. Party. You can use CyclicBarrier to write concurrency unit tests and implement generic algorithms in Java.

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.