CyclicBarrier in Java is a synchronizer
introduced in JDK 5 on java.util.Concurrent package along with other concurrent
utility like Counting Semaphore, BlockingQueue, ConcurrentHashMap etc.
CyclicBarrier is similar to
CountDownLatch which allows multiple threads to wait for each other (barrier)
before proceeding. CyclicBarrier is a natural requirement
for a concurrent program because it can be used to perform final part of the
task once individual tasks are completed.
All threads which wait for each other to
reach barrier are called parties, CyclicBarrier is initialized with a number of
parties to wait and threads wait for each other by calling
CyclicBarrier.await() method which is a blocking method in Java and blocks until all Thread or parties call
await().
In general calling await() is shout out
that Thread is waiting on the barrier.
await() is a blocking call but can be
timed out or Interrupted by other thread.
If you look at CyclicBarrier, it also the
does the same thing but there is different you cannot reuse CountDownLatch once
the count reaches zero while you can reuse CyclicBarrier by calling reset ()
method which resets Barrier to its initial State.
What it implies that CountDownLatch is a
good for one-time events like application start-up time and CyclicBarrier can
be used to in case of the recurrent event e.g. concurrently calculating a
solution of the big problem etc.
Example
Here is a
simple example of CyclicBarrier in Java on which we initialize CyclicBarrier
with 3 parties, means in order to cross barrier, 3 thread needs to call await()
method.
Each
thread calls await method in short duration but they don't proceed until all 3
threads reached the barrier, once all thread reach the barrier, barrier gets
broker and each thread started their execution from that point.
It’s much
clear with the output of following example of CyclicBarrier in Java:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Java program to demonstrate how to use CyclicBarrier in Java. CyclicBarrier is a
* new Concurrency
Utility added in Java 5 Concurrent package.
*
*/
public class CyclicBarrierExample {
//Runnable task for each thread
private static class Task implements Runnable {
private CyclicBarrier barrier;
public Task(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " is waiting on barrier");
barrier.await();
System.out.println(Thread.currentThread().getName() + " has crossed the barrier");
} catch (InterruptedException ex) {
Logger.getLogger(CyclicBarrierExample.class.getName()).log(Level.SEVERE, null, ex);
} catch (BrokenBarrierException ex) {
Logger.getLogger(CyclicBarrierExample.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String args[]) {
//creating CyclicBarrier with 3 parties i.e. 3 Threads needs to call await()
final CyclicBarrier cb = new CyclicBarrier(3, new Runnable(){
@Override
public void run(){
//This task will be executed once all thread reaches barrier
System.out.println("All parties are arrived at barrier, lets play");
}
});
//starting each of thread
Thread t1 = new Thread(new Task(cb), "Thread 1");
Thread t2 = new Thread(new Task(cb), "Thread 2");
Thread t3 = new Thread(new Task(cb), "Thread 3");
t1.start();
t2.start();
t3.start();
}
}
*/
public class CyclicBarrierExample {
//Runnable task for each thread
private static class Task implements Runnable {
private CyclicBarrier barrier;
public Task(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " is waiting on barrier");
barrier.await();
System.out.println(Thread.currentThread().getName() + " has crossed the barrier");
} catch (InterruptedException ex) {
Logger.getLogger(CyclicBarrierExample.class.getName()).log(Level.SEVERE, null, ex);
} catch (BrokenBarrierException ex) {
Logger.getLogger(CyclicBarrierExample.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String args[]) {
//creating CyclicBarrier with 3 parties i.e. 3 Threads needs to call await()
final CyclicBarrier cb = new CyclicBarrier(3, new Runnable(){
@Override
public void run(){
//This task will be executed once all thread reaches barrier
System.out.println("All parties are arrived at barrier, lets play");
}
});
//starting each of thread
Thread t1 = new Thread(new Task(cb), "Thread 1");
Thread t2 = new Thread(new Task(cb), "Thread 2");
Thread t3 = new Thread(new Task(cb), "Thread 3");
t1.start();
t2.start();
t3.start();
}
}
Output:
Thread 1 is waiting on barrier
Thread 3 is waiting on barrier
Thread 2 is waiting on barrier
All parties have arrived at barrier, lets play
Thread 3 has crossed the barrier
Thread 1 has crossed the barrier
Thread 2 has crossed the barrier
When to use CyclicBarrier in Java
Given the nature of CyclicBarrier it can
be very handy to implement map reduce kind of task similar to fork-join
framework of Java 7, where a big task is broken down into smaller pieces and to
complete the task you need output from individual small task
e.g. to count population of India you can have
4 threads which count population from North, South, East, and West and once
complete they can wait for each other, When last thread completed their task,
Main thread or any other thread can add result from each zone and print total
population. You can use CyclicBarrier in Java :
1.
To
implement multi player game which cannot begin until all player has joined.
2.
Perform
lengthy calculation by breaking it into smaller individual tasks, In general,
to implement Map reduce technique.
Important point of CyclicBarrier in Java
1.
CyclicBarrier
can perform a completion task once all thread reaches to the barrier, this can
be provided while creating CyclicBarrier.
2.
If
CyclicBarrier is initialized with 3 parties means 3 thread needs to call await
method to break the barrier.
3.
The
thread will block on await() until all parties reach to the barrier, another
thread interrupt or await timed out.
4.
If
another thread interrupts the thread which is waiting on barrier it will throw
BrokernBarrierException as shown below:
java.util.concurrent.BrokenBarrierException
at
java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:172)
at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:327)
5.
CyclicBarrier.reset()
put Barrier on its initial state, other thread which is waiting or not yet
reached barrier will terminate with
java.util.concurrent.BrokenBarrierException.
[Multithreading Interview Questions]
We recommend you take Big Data Hadoop class room training at eMexo Technologies in electronic city, Bangalore to learn more about Big Data Hadoop.