CyclicBarrier類似於CountDownLatch也是個計數器, 不同的是CyclicBarrier數的是調用了CyclicBarrier.await()進入等待的線程數, 當線程數達到了CyclicBarrier初始時規定的數目時,所有進入等待狀態的線程被喚醒並繼續。 CyclicBar... ...
一、CyclicBarrier
CyclicBarrier是一個同步輔助類,它允許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。在涉及一組固定大小的線程的程式中,這些線程必須不時地互相等待,此時 CyclicBarrier 很有用。因為該 barrier 在釋放等待線程後可以重用,所以稱它為迴圈 的 barrier。
CyclicBarrier類似於CountDownLatch也是個計數器, 不同的是CyclicBarrier數的是調用了CyclicBarrier.await()進入等待的線程數, 當線程數達到了CyclicBarrier初始時規定的數目時,所有進入等待狀態的線程被喚醒並繼續。 CyclicBarrier就象它名字的意思一樣,可看成是個障礙, 所有的線程必須到齊後才能一起通過這個障礙。 CyclicBarrier初始時還可帶一個Runnable的參數,此Runnable任務在CyclicBarrier的數目達到後,所有其它線程被喚醒前被執行。
A、構造函數 創建一個新的 CyclicBarrier,它將在給定數量的參與者(線程)處於等待狀態時啟動,但它不會在每個 barrier 上執行預定義的操作。
public CyclicBarrier(int parties) { this(parties, null);}
demo:
1 package com.jalja.org.thread; 2 import java.util.concurrent.CyclicBarrier; 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 public class LockTest { 6 public static void main(String [] args){ 7 CyclicBarrier cyclicBarrier = new CyclicBarrier(3); 8 ExecutorService executorService= Executors.newFixedThreadPool(3); 9 Runnable threadTest=null; 10 for(int i=0;i<3;i++){ 11 threadTest=new ThreadTest(cyclicBarrier); 12 executorService.execute(threadTest); 13 } 14 executorService.shutdown(); 15 } 16 } 17 class ThreadTest implements Runnable{ 18 private CyclicBarrier cyclicBarrier; 19 public ThreadTest(CyclicBarrier cyclicBarrier){ 20 this.cyclicBarrier=cyclicBarrier; 21 } 22 public void run() { 23 try { 24 Thread.sleep((long)(Math.random()*10000)); 25 System.out.println(Thread.currentThread().getName()+"開始執行"); 26 cyclicBarrier.await(); 27 }catch (Exception e){ 28 e.printStackTrace(); 29 } 30 System.out.println(Thread.currentThread().getName()+"執行結束"); 31 } 32 }View Code
B、構造函數 創建一個新的 CyclicBarrier,它將在給定數量的參與者(線程)處於等待狀態時啟動,併在啟動 barrier時執行給定的屏障操作,該操作由最後一個進入 barrier 的線程執行
public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; }
demo: 如果在構造CyclicBarrier對象的時候傳了一個Runnable對象進去,則每次到達公共屏障點的時候都最先執行這個傳進去的Runnable,然後再執行處於等待的Runnable。如果把上面的例子改成下麵這樣:
1 package com.jalja.org.thread; 2 import java.util.concurrent.CyclicBarrier; 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 public class LockTest { 6 public static void main(String [] args){ 7 CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() { 8 public void run() { 9 System.out.println(Thread.currentThread().getName()+"======"); 10 try { 11 Thread.sleep((long)(Math.random()*10000)); 12 }catch (Exception e){ 13 e.printStackTrace(); 14 } 15 System.out.println(Thread.currentThread().getName()+"======>"); 16 } 17 }); 18 ExecutorService executorService= Executors.newFixedThreadPool(3); 19 Runnable threadTest=null; 20 for(int i=0;i<3;i++){ 21 threadTest=new ThreadTest(cyclicBarrier); 22 executorService.execute(threadTest); 23 } 24 executorService.shutdown(); 25 } 26 } 27 class ThreadTest implements Runnable{ 28 private CyclicBarrier cyclicBarrier; 29 public ThreadTest(CyclicBarrier cyclicBarrier){ 30 this.cyclicBarrier=cyclicBarrier; 31 } 32 public void run() { 33 try { 34 Thread.sleep((long)(Math.random()*10000)); 35 System.out.println(Thread.currentThread().getName()+"開始執行"); 36 cyclicBarrier.await(); 37 }catch (Exception e){ 38 e.printStackTrace(); 39 } 40 System.out.println(Thread.currentThread().getName()+"執行結束"); 41 } 42 }View Code
結果:
pool-1-thread-2開始執行 pool-1-thread-3開始執行 pool-1-thread-1開始執行 pool-1-thread-1====== pool-1-thread-1======> pool-1-thread-1執行結束 pool-1-thread-2執行結束 pool-1-thread-3執行結束