In last post we had talked about CountDownLatch and seen a good use case around computer login. We have seen that in countdown latch participant threads in waiting and running were different.
Next utility is CyclicBarrier. In this same threads participate as running and then waiting. CyclicBarrier comes under java.util.concurrent package.
While initialising CyclicBarrier we can give how many threads will wait on barrier, until last thread arrives.
CyclicBarrier barrier = new CyclicBarrier(3);
barrier can also have action associated to it… which we will see in example below.
Final piece of picture is Job that will have barrier.await() in some line to create barrier at that step. All threads will start executing this job and wait at barrier till last threads comes.
Use Case
CyclicBarrier is useful where execution is divided into steps. Threads can execute in any order but until barrier is reached. At barrier threads will wait till last thread reaches. Threads will continue execution after barrier.
Example
I am taking very interesting example around meal preparing machine in Mcdonalds.
We have McdonaldsMealTask class which acts as Job and prepares your meal order. Threads BurgerMachine, FriesMachine and ColaMachine will be started and execute their part of Job.
Once meal is complete then await() method will be called to finish order and deliver. So Burger or Fries or Cola can be prepared in any sequence but threads will wait till last item of meal is done.
CyclicBarrierExample class will create and start threads for your meal.
One more thing – I have created barrierAction which is implementation of Runnable. we can provide action that is required to execute when this barrier is reached. This is optional step. You can have CyclicBarrier without barrierAction also.
Let’s go through example and mcdonald meal.
package com.alychidesigns.examples;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* Lets implement Cyclic Barrier Example for preparing meals at Mcdonalds.
* Meal will have Burger, Fries and cola, which will be prepared by 3 threads.
* When all 3 threads have worked. Meal is prepared so barrier will reached.
*
* @author Aly.Chiman
*
*/
// Mcdonalds Job
class McdonaldsMealTask implements Runnable {
private final CyclicBarrier barrier;
public McdonaldsMealTask(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(“Thread starting :-” + threadName);
switch (threadName) {
case “BurgerMachine”:
System.out.println(“Preparing Burger”);
break;
case “FriesMachine”:
System.out.println(“Preparing Fries”);
break;
case “ColaMachine”:
System.out.println(“Preparing Cola”);
break;
}
try {
this.barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(“Thread finished :-” + threadName);
}
}
// Thread Manager class.
public class CyclicBarrierExample {
public static void main(String[] args) {
Runnable barrierAction = new Runnable() {
@Override
public void run() {
System.out.println(“Order Complete. Put in Tray and deliver”);
}
};
CyclicBarrier barrier = new CyclicBarrier(3, barrierAction);
McdonaldsMealTask task = new McdonaldsMealTask(barrier);
new Thread(task,”BurgerMachine”).start();
new Thread(task,”FriesMachine”).start();
new Thread(task,”ColaMachine”).start();
}
}
..Feeling hungry … đŸ™‚
Wait Output is here
Thread starting :-FriesMachine
Thread starting :-BurgerMachine
Thread starting :-ColaMachine
Preparing Burger
Preparing Fries
Preparing Cola Order Complete. Put in Tray and deliver
Thread finished :-FriesMachine
Thread finished :-BurgerMachine
Thread finished :-ColaMachine
So threads are waiting for order to complete (barrier), then only they will move forward.
Hope you will like this interesting, easy and foodie type example.