Learnitweb

CyclicBarrier in Java

1. Introduction

The CyclicBarrier allows a set of threads to all wait for each other to reach a common barrier point. This class is similar to the CountDownLatch class but the barrier in this case is reusable after the waiting threads are released and hence the name cyclic.

CyclicBarrier is used when there is a group of threads working together to solve a problem and occasionally have to wait for each other. Each thread calls await() once it reaches a determined point which is the barrier. When the last thread reaches the barrier and calls await(), it breaks the barrier and all threads start processing again.

A typical flow in case of CyclicBarrier is:

  • A main thread is created.
  • The main thread creates cyclic barrier with some initial value.
  • The main thread creates other party threads and starts other threads.
  • Each party threads when reaches a certain determined point called barrier, calls await() method. This tells other threads that it has reached barrier and will wait.
  • When the last thread calls await(), barrier is broken and the threads can start processing.

CyclicBarrier can be used instead of CountDownLatch but not vice-versa.

If a thread doesn’t reach the barrier point prematurely because of failure, timeout or interruption, all other threads waiting at the barrier point will also leave by throwing BrokenBarrierException or InterruptedException.

2. Example of CyclicBarrier

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

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

class Party extends Thread {
	private CyclicBarrier barrier;

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

	@Override
	public void run() {
		try {
			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 Thread-2 is calling await()
Party Thread-4 is calling await()
Party Thread-1 is calling await()
Party Thread-3 is calling await()
Party Thread-3 has started running again
Party Thread-1 has started running again
Party Thread-4 has started running again
Party Thread-2 has started running again

As you can see, we have created 4 threads and each thread calls await() once it reaches barrier. Till all the party threads have reached barrier, none of the threads start working again. Once the last thread calls await(), the barrier is broken and the threads start processing again.