一個同步輔助類,它容許一組線程互相等待,直到到達某個公共屏障點 (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