In our previous series of CyclicBarrier we learned that CyclicBarrier can be constructed in two ways.
Like
In this series we look for the use of the second constructor , which takes only one integer argument,the number of parallel threads.
package com.brainatjava.test;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierConstructorWithOneArgument {
private static int matrix[][] =
{
{ 1 ,1,1,1},
{ 2, 2 ,2,2},
{ 3, 3, 3 ,3},
{ 4, 4, 4, 4 },
{ 5, 5, 5, 5 } };
private static int results[];
private static class Adder extends Thread
{
int row;
CyclicBarrier barrierWhereAllThreadsWillWait;
Adder(CyclicBarrier cb, int row)
{
this.barrierWhereAllThreadsWillWait = cb;
this.row = row;
}
public void run()
{
int columns = matrix[row].length;
int sum = 0;
for (int i = 0; i < columns; i++)
{
sum += matrix[row][i];
}
results[row] = sum;
System.out.println("Results for row " + row + " are : " + sum);
int arrivalIndex=0;
try
{
arrivalIndex= barrierWhereAllThreadsWillWait.await();
} catch (InterruptedException ex)
{
ex.printStackTrace();
} catch (BrokenBarrierException ex)
{
ex.printStackTrace();
}
if(arrivalIndex==0){
System.out.println(Thread.currentThread().getName()+" is executing the combined result.");
int total = 0;
for (int i = 0; i < results.length; i++)
{
total += results[i];
}
System.out.println("Results are: " + total);
}
}
}
public static void main(String args[])
{
final int rows = matrix.length;
results = new int[rows];
CyclicBarrier barrier = new CyclicBarrier(rows);
for (int i = 0; i < rows; i++)
{
new Adder(barrier, i).start();
}
}
}
In the above code snippet ,Please note the line highlighted with red color.Here the await() method of cyclicbarrier class is returning an int value.That signifies the arrival index of the thread at the barrier.
If the arrival index is zero ,it means that thread is the last thread to arrive at the barrier.
Here we choose the last thread that reaches at the barrier to execute the final action that is to calculate the total sum.Since we have taken the arrival index of the thread as zero.
Like
CyclicBarrier cb=new
CyclicBarrier (int nosOfPArallelThread,Runnable BarrierAction);
CyclicBarrier cb=new
CyclicBarrier (int nosOfParallelThread);
In
our previous series we saw an example of first constructor, which takes two parameters numberofParallelThreads and a Runnable as argument.In this series we look for the use of the second constructor , which takes only one integer argument,the number of parallel threads.
package com.brainatjava.test;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierConstructorWithOneArgument {
private static int matrix[][] =
{
{ 1 ,1,1,1},
{ 2, 2 ,2,2},
{ 3, 3, 3 ,3},
{ 4, 4, 4, 4 },
{ 5, 5, 5, 5 } };
private static int results[];
private static class Adder extends Thread
{
int row;
CyclicBarrier barrierWhereAllThreadsWillWait;
Adder(CyclicBarrier cb, int row)
{
this.barrierWhereAllThreadsWillWait = cb;
this.row = row;
}
public void run()
{
int columns = matrix[row].length;
int sum = 0;
for (int i = 0; i < columns; i++)
{
sum += matrix[row][i];
}
results[row] = sum;
System.out.println("Results for row " + row + " are : " + sum);
int arrivalIndex=0;
try
{
arrivalIndex= barrierWhereAllThreadsWillWait.await();
} catch (InterruptedException ex)
{
ex.printStackTrace();
} catch (BrokenBarrierException ex)
{
ex.printStackTrace();
}
if(arrivalIndex==0){
System.out.println(Thread.currentThread().getName()+" is executing the combined result.");
int total = 0;
for (int i = 0; i < results.length; i++)
{
total += results[i];
}
System.out.println("Results are: " + total);
}
}
}
public static void main(String args[])
{
final int rows = matrix.length;
results = new int[rows];
CyclicBarrier barrier = new CyclicBarrier(rows);
for (int i = 0; i < rows; i++)
{
new Adder(barrier, i).start();
}
}
}
In the above code snippet ,Please note the line highlighted with red color.Here the await() method of cyclicbarrier class is returning an int value.That signifies the arrival index of the thread at the barrier.
If the arrival index is zero ,it means that thread is the last thread to arrive at the barrier.
Here we choose the last thread that reaches at the barrier to execute the final action that is to calculate the total sum.Since we have taken the arrival index of the thread as zero.
Reset Method of CyclicBarrier():
If reset() method is called by any thread, then all the other threads waiting at the barrier will awake by throwing a BrokenBarrierException.So we can say that the reset() method is used when we want to break the barrier forcibly.Remember that if one thread will call reset method when no other threads are waiting on barrier,then reset method has no effect.
Let's see the reset method in action with the help of an example.
package com.brainatjava.test;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class CyclicBarrierResetExample
{
public static void main(String args[])
{
CyclicBarrier cb=new CyclicBarrier(2,new Master());
Thread slave1=new Thread(new Slave1(cb));
slave1.start();
Thread slave2=new Thread( new Slave2(cb));
slave2.start();
}
}
class Slave1 implements Runnable
{
CyclicBarrier cb;
public Slave1(CyclicBarrier cb)
{
this.cb=cb;
}
public void run()
{
System.out.println("Slave1 has performed some work.");
System.out.println("Slave1 is going to wait.");
try
{
cb.await();
}catch(BrokenBarrierException e){
System.out.println("Slave1 can't wait as it is getting BrokenBArrier exception "+e.getMessage());
e.printStackTrace();
} catch (InterruptedException e) {
System.out.println("Slave1 can't wait as it is getting interupted exception "+e.getMessage());
e.printStackTrace();
}
System.out.println("Anyway !!!! Woo Slave1's waiting is finsihed.Slave1 is going home now.");
}
}
class Slave2 implements Runnable
{
CyclicBarrier cb;
public Slave2(CyclicBarrier cb)
{
this.cb=cb;
}
public void run()
{
System.out.println("Slave2 has performed some work.");
System.out.println("Slave2 is going to wait.");
try
{ Thread.sleep(1000);
cb.reset();
cb.await();
}catch(BrokenBarrierException e){
System.out.println("Slave2 can't wait as it is getting brokenbarrier exception "+e.getMessage());
} catch (InterruptedException e) {
System.out.println("Slave2 can't wait as it is getting nullpointer exception "+e.getMessage());
e.printStackTrace();
}
System.out.println("Anyway !!!! Woo Slave2's waiting is finsihed.Slave2 is going home now.");
}
}
class Master implements Runnable
{
public void run()
{
System.out.println("Master is going to complete all his work as two slaves have already reached at the barrier.");
System.out.println("Thank you slaves you completed all your work on time.");
}
}
Slave1 is going to wait.
Slave2 has performed some work.
Slave2 is going to wait.
Master is going to complete all his work as two slaves have already reached at the barrier.
Thank you slaves you completed all your work on time.
Anyway !!!! Woo Slave2's waiting is finsihed.Slave2 is going home now.
Slave1 can't wait as it is getting BrokenBArrier exception null
java.util.concurrent.BrokenBarrierException
at java.util.concurrent.CyclicBarrier.dowait(Unknown Source)
at java.util.concurrent.CyclicBarrier.await(Unknown Source)
at com.brainatjava.test.Slave1.run(CyclicBarrierResetExample.java:30)
at java.lang.Thread.run(Unknown Source)
Anyway !!!! Woo Slave1's waiting is finsihed.Slave1 is going home now.
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class CyclicBarrierResetExample
{
public static void main(String args[])
{
CyclicBarrier cb=new CyclicBarrier(2,new Master());
Thread slave1=new Thread(new Slave1(cb));
slave1.start();
Thread slave2=new Thread( new Slave2(cb));
slave2.start();
}
}
class Slave1 implements Runnable
{
CyclicBarrier cb;
public Slave1(CyclicBarrier cb)
{
this.cb=cb;
}
public void run()
{
System.out.println("Slave1 has performed some work.");
System.out.println("Slave1 is going to wait.");
try
{
cb.await();
}catch(BrokenBarrierException e){
System.out.println("Slave1 can't wait as it is getting BrokenBArrier exception "+e.getMessage());
e.printStackTrace();
} catch (InterruptedException e) {
System.out.println("Slave1 can't wait as it is getting interupted exception "+e.getMessage());
e.printStackTrace();
}
System.out.println("Anyway !!!! Woo Slave1's waiting is finsihed.Slave1 is going home now.");
}
}
class Slave2 implements Runnable
{
CyclicBarrier cb;
public Slave2(CyclicBarrier cb)
{
this.cb=cb;
}
public void run()
{
System.out.println("Slave2 has performed some work.");
System.out.println("Slave2 is going to wait.");
try
{ Thread.sleep(1000);
cb.reset();
cb.await();
}catch(BrokenBarrierException e){
System.out.println("Slave2 can't wait as it is getting brokenbarrier exception "+e.getMessage());
} catch (InterruptedException e) {
System.out.println("Slave2 can't wait as it is getting nullpointer exception "+e.getMessage());
e.printStackTrace();
}
System.out.println("Anyway !!!! Woo Slave2's waiting is finsihed.Slave2 is going home now.");
}
}
class Master implements Runnable
{
public void run()
{
System.out.println("Master is going to complete all his work as two slaves have already reached at the barrier.");
System.out.println("Thank you slaves you completed all your work on time.");
}
}
Output Of the Above Programme
Slave1 has performed some work.
Slave1 is going to wait.
Slave2 has performed some work.
Slave2 is going to wait.
Master is going to complete all his work as two slaves have already reached at the barrier.
Thank you slaves you completed all your work on time.
Anyway !!!! Woo Slave2's waiting is finsihed.Slave2 is going home now.
Slave1 can't wait as it is getting BrokenBArrier exception null
java.util.concurrent.BrokenBarrierException
at java.util.concurrent.CyclicBarrier.dowait(Unknown Source)
at java.util.concurrent.CyclicBarrier.await(Unknown Source)
at com.brainatjava.test.Slave1.run(CyclicBarrierResetExample.java:30)
at java.lang.Thread.run(Unknown Source)
Anyway !!!! Woo Slave1's waiting is finsihed.Slave1 is going home now.