Java并发编程之CyclicBarrier的使用

Java并发编程之CyclicBarrier的使用

 

先看javadoc对这个类的说明:A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.

什么时候用这个类?当有多个线程完成类似的任务,如果需要每个线程在执行任务中的某个地方停下来,等待其它线程也到达相同的等待点(其实不同的等待点也行),那这个类就完美解决了这个需求,比如(后面有代码):有多个跑步的人,各自跑的速度不一样,但是大家需要在中途某个点聚一聚,然后在一起出发。

 

以下是CyclicBarrier的public方法:

 
Java并发编程之CyclicBarrier的使用_第1张图片
 

关于两个参数的构造方法:


Java并发编程之CyclicBarrier的使用_第2张图片
 也就是说如果用了这个方法,那么当等待在await()方法上的线程数 = getParties() 时,该runnable会被最后一个等待的线程去跑。

 

 

关于reset()方法:


调用该方法时,若有线程等待在await方法上,则这些线程都会收到一个BrokenBarrierException异常。

 

关于isBroken()方法:

只要任何一个等待在await()方法上的线程非正常地从await()上返回,那么isBroken()就返回true。

 

示例:


说明:两个人AAA、BBB,分别以1m/s、2m/s速度跑,若跑到6m处时还有人未到达6m处,则等待所有人都到达时才出发。跑完10m结束

Java代码 
  1. package cyclicbarrier;  
  2.   
  3. import java.util.concurrent.BrokenBarrierException;  
  4. import java.util.concurrent.CyclicBarrier;  
  5.   
  6. public class RunningMan implements Runnable{  
  7.       
  8.     private int speed; // 1 m/s  
  9.     private int waitAfterMeters; // m  
  10.     private int totalMeters; // m  
  11.     private String name;  
  12.       
  13.     private CyclicBarrier barrier;  
  14.       
  15.     public RunningMan(int speed, int waitAfterMeters, int totalMeters) {  
  16.         this.speed = speed;  
  17.         this.waitAfterMeters = waitAfterMeters;  
  18.         this.totalMeters = totalMeters;  
  19.     }  
  20.       
  21.     public RunningMan barrier(CyclicBarrier barrier) {  
  22.         this.barrier = barrier;  
  23.         return this;  
  24.     }  
  25.       
  26.     public RunningMan name(String name) {  
  27.         this.name = name;  
  28.         return this;  
  29.     }  
  30.       
  31.     private boolean needToWait() {  
  32.         return barrier != null;  
  33.     }  
  34.       
  35.     private long time() {  
  36.         return System.currentTimeMillis() / 1000;  
  37.     }  
  38.       
  39.     @Override  
  40.     public void run() {  
  41.         System.out.println(time() + ": runningman " + name + " start running.");  
  42.         int ranMiles = 0;// 跑了多少m  
  43.         while (ranMiles < totalMeters) {  
  44.             // 跑1s  
  45.             try {  
  46.                 Thread.sleep(1000 * 1);  
  47.             } catch (InterruptedException e) {  
  48.                 // 当前线程被中断了,那就不跑了  
  49.                 Thread.currentThread().interrupt();  
  50.                 break;  
  51.             }  
  52.             //计数  
  53.             ranMiles += speed;  
  54.             //是否到达指定等待点  
  55.             if (ranMiles == waitAfterMeters) {  
  56.                 if (!needToWait()) { //没有barrier  
  57.                     continue;  
  58.                 }  
  59.                   
  60.                 // 是否是最后一个到达指定等待点的  
  61.                 if (barrier.getNumberWaiting() + 1 == barrier.getParties()) {  
  62.                     System.out.println(time() + ": runningman " + name + " is the last one reached at " + waitAfterMeters);  
  63.                 } else {  
  64.                     System.out.println(time() + ": runningman " + name + " reached at " + waitAfterMeters + ", waiting for others");  
  65.                 }  
  66.                 // 等待, 直到barrier.getNumberWaiting() == barrier.getParties()时返回  
  67.                 try {  
  68.                     barrier.await();  
  69.                 } catch (InterruptedException e) {  
  70.                     // 当前线程被中断了,那就不跑了  
  71.                     Thread.currentThread().interrupt();  
  72.                     break;  
  73.                 } catch (BrokenBarrierException e) {  
  74.                     System.err.println("someone reset the barrier state.");  
  75.                     break;  
  76.                 }  
  77.             } else {  
  78.                 System.out.println(time() + ": runningman " + name + " reached at " + ranMiles);  
  79.             }  
  80.         }  
  81.         System.out.println(time() + ": runningman " + name + " done running.");  
  82.     }  
  83.       
  84.     public static void main(String[] args) {  
  85.         CyclicBarrier barrier = new CyclicBarrier(2);  
  86.         RunningMan rm1 = new RunningMan(1610).name("AAA").barrier(barrier);  
  87.         RunningMan rm2 = new RunningMan(2610).name("BBB").barrier(barrier);  
  88.         Thread t1 = new Thread(rm1);  
  89.         Thread t2 = new Thread(rm2);  
  90.         t1.start();  
  91.         t2.start();  
  92.     }  
  93. }  

 结果:

 
Java并发编程之CyclicBarrier的使用_第3张图片

你可能感兴趣的:(Java,CyclicBarrier,多线程,concurrent包,Java)