What is CyclicBarrier in Java
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 we have seen in the last article
What is CountDownLatch in Java
and allows multiple threads to wait for each other (barrier) before
proceeding. The difference between CountDownLatch and CyclicBarrier is
also a very
popular multi-threading interview question
in Java. CyclicBarrier
is a natural requirement for a concurrent program because it can be used
to perform the final part of the task once individual tasks are completed.
All threads which wait for each other to reach the 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 a shout out that Thread is waiting on the barrier. await() is a blocking call but can be timed out or Interrupted by other threads.
In this Java concurrency tutorial, we will see What is CyclicBarrier in Java and an example of CyclicBarrier on which three Threads will wait for each other before proceeding further.
All threads which wait for each other to reach the 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 a shout out that Thread is waiting on the barrier. await() is a blocking call but can be timed out or Interrupted by other threads.
In this Java concurrency tutorial, we will see What is CyclicBarrier in Java and an example of CyclicBarrier on which three Threads will wait for each other before proceeding further.
And, if you are serious about mastering Java multi-threading and concurrency then I also suggest you take a look at the Java Multithreading, Concurrency, and Performance Optimization course by Michael Pogrebinsky on Udemy. It's an advanced course to become an expert in Multithreading, concurrency, and Parallel programming in Java with a strong emphasis on high performance
How to use CyclicBarrier in Java – Example
Now we know what is CyclicBarrier in Java and it's time to see an example
of CyclicBarrier in Java. Here is a simple example of CyclicBarrier in Java on which we initialize CyclicBarrier
with 3 parties, means in order to cross the 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 reaches the barrier, the barrier gets broker and each thread started their execution from that point. It's much clear with the output of the following example of CyclicBarrier in Java:
Each thread calls await method in short duration but they don't proceed until all 3 threads reached the barrier, once all thread reaches the barrier, the barrier gets broker and each thread started their execution from that point. It's much clear with the output of the 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
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.
*
* @author Javin Paul
*/
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 the barrier
Thread 3 is waiting on the barrier
Thread 2 is waiting on the barrier
All parties have arrived at the barrier, lets play
Thread 3 has crossed the barrier
Thread 1 has crossed the barrier
Thread 2 has crossed the barrier
* @author Javin Paul
*/
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 the barrier
Thread 3 is waiting on the barrier
Thread 2 is waiting on the barrier
All parties have arrived at the 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? Example
Given the nature of CyclicBarrier,
it can be very handy to implement map-reduce kind of task similar to
the 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 the individual small task.
For example, to count the 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 multiplayer game which can not begin until all player has
joined.
2) Perform lengthy calculation by breaking it into smaller individual
tasks, In general, to implement Map reduce technique.
If you want to learn more about CyclicBarrier in Java, then you can
further check the Multithreading and Parallel Computing in Java course
on Udemy, it's a good course to learn multithreading basics in Java and
you can buy in just $10 on Udemy sales.
Difference between CountDownLatch and CyclicBarrier in Java
In our last article, we have to see how CountDownLatch can be used to implement multiple threads waiting for each other. If you look at CyclicBarrier it also does the same thing but it is different you can not reuse CountDownLatch once the count reaches zero while you can reuse CyclicBarrier by calling the reset() method which resets Barrier to its initial State.
What it implies that CountDownLatch is good for one-time events like application start-up time and CyclicBarrier can be used in case of the recurrent event like concurrently calculating a solution of the big problem etc.
What it implies that CountDownLatch is good for one-time events like application start-up time and CyclicBarrier can be used in case of the recurrent event like concurrently calculating a solution of the big problem etc.
If you like to learn more about threading and concurrency in Java you
can also check my post on When to use the Volatile variable in Java and How Synchronization works in Java.
Important points 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 the await
method to break the barrier.
3.
The thread will block
on await()
until all parties reach the barrier, another thread interrupts or await timed out.
4. If another thread interrupts the thread which is waiting on the
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)
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.
That's all on What is CyclicBarrier in Java When to use CyclicBarrier in Java and a Simple Example of
How to use CyclicBarrier in Java. We have also seen the difference between CountDownLatch and CyclicBarrier
in Java and got some idea where we can use CyclicBarrier in Java Concurrent code.
Other Java thread and concurrency tutorials from Javarevisited
Blog
- Why wait and notify methods are declared in an Object class
- How to avoid deadlock in Java by carefully coding
- What is a race condition in a concurrent Java program?
- How to write a thread-safe class in Java
- Difference between Runnable and Thread in Java
- 5 Best Courses to learn Multithreading in Java
- 6 Books to learn Concurrency and Threads in Java
- What is happens-before in Java?
- How to use Exchanger to share objects in Java?
- Difference between volatile, atomic, and synchronized in Java
- How Thread, Code, and Data works in Java Program
Thanks for reading this article of far. If you find this CyclicBarrier
tutorial useful then please share it with your friends and colleagues. If
you have any questions or feedback then please drop a note.
Now, over to you, what is difference between Phaser and CyclicBarrier in Java? and What is your favorite Concurrency utility like CyclicBarrier, CountDownLatch, Semaphore, Phaser, CompletableFuture or anything else?
11 comments :
Using a barrier in a parallel calculation isn't the best example. You'd end up tying resources needlessly while they could be doing something useful - such as calculating more parts. Most implementations use an intermediate results repository and take threads from a pool according to need.
@Ran Biron, Thanks for your comments. This CyclicBarrier example was to demonstrate How main thread wait for supporting thread at a particular point. I think CyclicBarrier has real use case around multi-player games where Game should be start until all parties arrived and as you rightly pointed out initializing different parts of system etc.
Another key difference between CyclicBarrier vs CountDownLatch is that later is advanceble. By advanceble, I mean thread can still continue e.g. Threads waiting on CountDownLatch can still continue after calling countDown() method but In CyclicBarrier, all thread must wait at barrier for other parties to arrive. That's why CyclicBarrier is not advanceable.
"..You can use CyclicBarrier in Java :
1) To implement multi player game which can not begin until all player has joined."
While I can see how one might be able to use a CyclicBarrier for the multi player example, a CountDown latch is actually more relevant here. Latches are precisely meant for this use - a one off event where some control thread wants to wait for N number of other threads before proceeding. As a matter of fact, that specific example (the multi-player example) is used in the Java concurrency in Practice book (5.5.1).
There is one scenario where We have 3 Producer P1,P2,P3 and 3 Consumer C1,C2,C3,. The producer produce the X1,X2,X3 in random order and put in to Queue. Now I want to consume the things like C1 consume [X1,X2,X3] same like C2 [Y1,Y2,Y3] ….where the queue contains [x1,x2,y1,x3,y2,y3....]… How to implement this things
Great example, here is one more example of how you can use CyclicBarrier in Java to stop multiple threads at barrier point with easy to understand explanation.
What is difference between CyclicBarrier, CountDownLatch and Phaser in Java? When to use each of them or can we use them interchangebly?
What I have understood is:
1) Cyclic barrier can be reused by calling reset method
2) The main thread does not block for reaching all parties to barrier.
3) The Worker thread, which is passed as second argument to CyclicBarrier constructor, waits for all parties to reach barrier.
4) All parties call await() to signal that they have reached barrier.
5) Worker thread which was supplied to CyclicBarrier constructor perform its work once all parties reached barrier
6) Now, parties start working with further work.
Hello GG, yes your understanding is correct.
"When last thread completed their task, Main thread or any other thread can add result from each zone and print total population."
Here is a correction that, the last thread who calls the await() thread will add result from each zone i.e. barrier action. Not the main thread or any thread
Hello Sachin,
I think that is just one pattern, it totally depends upon your code and what you are doing in task. If all three threads are calculating the finish after executing their calculation then the thread which is alive like main thread can sum up their task.
Post a Comment