CyclicBarrier is a thread syncronization mechanism in which all the threads are requested to wait at a certain point, before all of them move forward. The specific point is called a barrier and threads enter into a wait state at barrier point until all working threads reaches at that point. Once all threads reaches barrier point, they are allowed to continue.
The importance of a Cyclic Barrier is that it is cyclic i.e. once all the threads reaches barrier point and resumes their individual jobs, CyclicBarrier is allowed to reset.
Here is an example of a Cricket Match. Before a bowler is allowed to bowl first delivery, it waits for 2 umpires to reach their specific positions and all 10 fielders at their respective fielding positions. Until and unless 2 umpires and 11 fielders reaches at their respective positions, no thread can move forward. For example, even if 2 umpires and 10 fielders reach their points, they still need to wait for 11th player to reach to his position. Once 11th player reaches his position and calls await() method, bowler is allowed to bowl.
Here is a real time implementation of CyclicBarrier
CyclicBarrierCricket.java - This is a main class that initializes CyclicBarrier. It initializes threads for 11 Players and 2 Umpires and then calls the await method(). As soon as both the umpires and 11 players calls await(), this thread moves forward.
package com.cyclicbarrier.learning; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierCricket { public static void main(String args[]) { CyclicBarrier barrier = new CyclicBarrier(14); System.out.println("Match about to Start"); System.out.println("Initializing Umpires"); for (int i = 1; i <= 2; i++) { CyclicBarrierUmpire barrierUmpire = new CyclicBarrierUmpire(); barrierUmpire.setUmpireNumber(i); barrierUmpire.setCyclicBarrier(barrier); Thread thread = new Thread(barrierUmpire); thread.start(); } System.out.println("Umpires Thread Started"); System.out.println("Initializing Players"); for (int i = 1; i <= 11; i++) { CyclicBarrierPlayers cyclicBarrierPlayers = new CyclicBarrierPlayers(); cyclicBarrierPlayers.setPlayerNumber(i); cyclicBarrierPlayers.setCyclicBarrier(barrier); Thread thread = new Thread(cyclicBarrierPlayers); thread.start(); } System.out.println("Players Thread Started"); try { barrier.await(); } catch (InterruptedException | BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Players and Umpires all set at their respective Positions. Lets start a Game"); } }
CyclicBarrierUmpire.java - This is a Java thread to initialize both the umpires. Both the umpires calls the await() method to notify that we are all set and waiting for rest of the players to move to the position.
package com.cyclicbarrier.learning; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierUmpire implements Runnable { private CyclicBarrier cyclicBarrier; private int umpireNumber; @Override public void run() { System.out.println("Umpire " + umpireNumber + " Moving to Position"); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Umpire " + umpireNumber + " Set at Position"); try { cyclicBarrier.await(); } catch (InterruptedException | BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Umpire - " + umpireNumber + " all set"); } public int getUmpireNumber() { return umpireNumber; } public void setUmpireNumber(int umpireNumber) { this.umpireNumber = umpireNumber; } public CyclicBarrier getCyclicBarrier() { return cyclicBarrier; } public void setCyclicBarrier(CyclicBarrier cyclicBarrier) { this.cyclicBarrier = cyclicBarrier; } }
CyclicBarrierPlayers.java - This is a Java thread to initialize all the players. All 11 players calls the await() method to notify that we are all set and waiting for rest of the players to move to the position. As soon as 11th player calls await() method, main class moves forward and allows a match to start.
package com.cyclicbarrier.learning; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierPlayers implements Runnable { private CyclicBarrier cyclicBarrier; private int playerNumber; @Override public void run() { System.out.println("Player " + playerNumber + " Moving to Fielding Position"); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Player " + playerNumber + " Fielding Position Set"); try { cyclicBarrier.await(); } catch (InterruptedException | BrokenBarrierException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Player - " + playerNumber + " all set"); } public CyclicBarrier getCyclicBarrier() { return cyclicBarrier; } public void setCyclicBarrier(CyclicBarrier cyclicBarrier) { this.cyclicBarrier = cyclicBarrier; } public int getPlayerNumber() { return playerNumber; } public void setPlayerNumber(int playerNumber) { this.playerNumber = playerNumber; } }
Output -
Match about to Start Initializing Umpires Umpires Thread Started Initializing Players Umpire 1 Moving to Position Umpire 2 Moving to Position Player 1 Moving to Fielding Position Player 2 Moving to Fielding Position Player 3 Moving to Fielding Position Player 4 Moving to Fielding Position Player 5 Moving to Fielding Position Player 6 Moving to Fielding Position Player 7 Moving to Fielding Position Player 8 Moving to Fielding Position Player 9 Moving to Fielding Position Players Thread Started Player 10 Moving to Fielding Position Player 11 Moving to Fielding Position Umpire 1 Set at Position Umpire 2 Set at Position Player 1 Fielding Position Set Player 4 Fielding Position Set Player 5 Fielding Position Set Player 8 Fielding Position Set Player 3 Fielding Position Set Player 2 Fielding Position Set Player 9 Fielding Position Set Player 7 Fielding Position Set Player 6 Fielding Position Set Player 11 Fielding Position Set Player 10 Fielding Position Set Player - 10 all set Umpire - 1 all set Players and Umpires all set at their respective Positions. Lets start a Game Umpire - 2 all set Player - 1 all set Player - 5 all set Player - 4 all set Player - 8 all set Player - 7 all set Player - 9 all set Player - 6 all set Player - 11 all set Player - 2 all set Player - 3 all set
Its clearly visible, main client prints "Players and Umpires all set at their respective Positions. Lets start a Game" only when all the Umpire and Player threads have called the await() method. Till then it was in wait state.
No comments:
Post a Comment