一个同步辅助类,它容许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 颇有用。由于该 barrier 在释放等待线程后能够重用,因此称它为循环 的 barrier。
CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达以后(但在释放全部线程以前),该命令只在每一个屏障点运行一次。若在继续全部参与线程以前更新共享状态,此屏障操做 颇有用。
CountDownLatch介绍:http://my.oschina.net/jielucky/blog/157946 java
package com.thread.cyclicBarrier; /** * Java线程:新特征-障碍器 -主线程 * @author wangjie * */ public class MainTask implements Runnable { @Override public void run() { System.out.println("主线程执行了"); } }
package com.lucky.concurrent.cyclicBarrier; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * Java线程:新特征-障碍器 -子线程 * * @author wangjie * */ public class ChildTask extends Thread { private CyclicBarrier cb; private static int index = 0; ChildTask(CyclicBarrier cb) { this.cb = cb; } @Override public void run() { try { if (index >= 2) { Thread.sleep(3000); } index++; System.out.println("子线程执行完毕,通知主线程"); // 注:这里parties里的计数在运行时当调用CyclicBarrier:await()时,计数就加1,一直加到初始的值 cb.await(); // 通知障碍器已经完成 System.out.println("必定要等到主线程执行以后才会执行 awati() 下面的 代码"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }
package com.thread.cyclicBarrier; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Java线程:新特征-障碍器 * * @author wangjie 2013-08-26 17:03:10 */ public class TestCyclicBarrier { public void run() { // 建立障碍器,并设置MainTask为全部定数量的线程都达到障碍点时候所要执行的任务(Runnable) CyclicBarrier cb = new CyclicBarrier(4, new MainTask()); ExecutorService pool = Executors.newCachedThreadPool(); pool.execute(new ChildTask(cb)); pool.execute(new ChildTask(cb)); pool.execute(new ChildTask(cb)); pool.execute(new ChildTask(cb)); pool.shutdown(); // pool.shutdownNow();//有线程还没执行完,不能当即中止。只能调用shutdown() } public static void main(String[] args) { new TestCyclicBarrier().run(); } }
执行结果能够看出,全部子任务完成的时候,主任务执行了,达到了控制的目标。
注:这里parties里的计数在运行时当调用CyclicBarrier:await()时,计数就加1,一直加到初始的值。
如下比方是摘录其余文章: 多线程
CountDownLatch 是计数器, 线程完成一个就记一个, 就像 报数同样, 只不过是递减的. 并发
CyclicBarrier更像一个水闸, 线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流. PS:这个形容很到位滴。
ide