CyclicBarrier

  CyclicBarrier是一個同步輔助類,它容許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。在涉及一組固定大小的線程的程序中,這些線程必須不時地互相等待,此時 CyclicBarrier 頗有用。由於該 barrier 在釋放等待線程後能夠重用,因此稱它爲循環 的 barrier。html

  CyclicBarrier相似於CountDownLatch也是個計數器, 不一樣的是CyclicBarrier數的是調用了CyclicBarrier.await()進入等待的線程數, 當線程數達到了CyclicBarrier初始時規定的數目時,全部進入等待狀態的線程被喚醒並繼續。 CyclicBarrier就象它名字的意思同樣,可當作是個障礙, 全部的線程必須到齊後才能一塊兒經過這個障礙。 CyclicBarrier初始時還可帶一個Runnable的參數,此Runnable任務在CyclicBarrier的數目達到後,全部其它線程被喚醒前被執行。java

構造方法摘要
CyclicBarrier(int parties) 
          建立一個新的 CyclicBarrier,它將在給定數量的參與者(線程)處於等待狀態時啓動,但它不會在每一個 barrier 上執行預約義的操做。
CyclicBarrier(int parties, Runnable barrierAction) 
          建立一個新的 CyclicBarrier,它將在給定數量的參與者(線程)處於等待狀態時啓動,並在啓動 barrier 時執行給定的屏障操做,該操做由最後一個進入 barrier 的線程執行

 

方法摘要
int await() 
          在全部參與者都已經在此 barrier 上調用 await 方法以前,將一直等待。
int await(long timeout, TimeUnit unit) 
          在全部參與者都已經在此屏障上調用 await 方法以前,將一直等待。
int getNumberWaiting() 
          返回當前在屏障處等待的參與者數目。
int getParties() 
          返回要求啓動此 barrier 的參與者數目。
boolean isBroken() 
          查詢此屏障是否處於損壞狀態。
void reset() 
          將屏障重置爲其初始狀態。

 

複製代碼

1 package com.thread;
 2 import java.util.concurrent.CyclicBarrier;
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 import java.util.concurrent.Semaphore;
 6 
 7 public class CyclicBarrierTest {
 8 
 9     public static void main(String[] args) {
10         ExecutorService service = Executors.newCachedThreadPool();
11         final  CyclicBarrier cb = new CyclicBarrier(3);//建立CyclicBarrier對象並設置3個公共屏障點
12         for(int i=0;i<3;i++){
13             Runnable runnable = new Runnable(){
14                     public void run(){
15                     try {
16                         Thread.sleep((long)(Math.random()*10000));    
17                         System.out.println("線程" + Thread.currentThread().getName() + 
18                                 "即將到達集合地點1,當前已有" + cb.getNumberWaiting() + "個已經到達,正在等候");                        
19                         cb.await();//到此若是沒有達到公共屏障點,則該線程處於等待狀態,若是達到公共屏障點則全部處於等待的線程都繼續往下運行
20                         
21                         Thread.sleep((long)(Math.random()*10000));    
22                         System.out.println("線程" + Thread.currentThread().getName() + 
23                                 "即將到達集合地點2,當前已有" + cb.getNumberWaiting() + "個已經到達,正在等候");                        
24                         cb.await();    
25                         Thread.sleep((long)(Math.random()*10000));    
26                         System.out.println("線程" + Thread.currentThread().getName() + 
27                                 "即將到達集合地點3,當前已有" + cb.getNumberWaiting() + "個已經到達,正在等候");                        
28                         cb.await();                        
29                     } catch (Exception e) {
30                         e.printStackTrace();
31                     }                
32                 }
33             };
34             service.execute(runnable);
35         }
36         service.shutdown();
37     }
38 }

複製代碼

複製代碼

線程pool-1-thread-1即將到達集合地點1,當前已有0個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點1,當前已有1個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點1,當前已有2個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點2,當前已有0個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點2,當前已有1個已經到達,正在等候
線程pool-1-thread-1即將到達集合地點2,當前已有2個已經到達,正在等候
線程pool-1-thread-1即將到達集合地點3,當前已有0個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點3,當前已有1個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點3,當前已有2個已經到達,正在等候

複製代碼

 

  若是在構造CyclicBarrier對象的時候傳了一個Runnable對象進去,則每次到達公共屏障點的時候都最早執行這個傳進去的Runnable,而後再執行處於等待的Runnable。若是把上面的例子改爲下面這樣:dom

複製代碼

1 package com.thread;
 2 import java.util.concurrent.CyclicBarrier;
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 import java.util.concurrent.Semaphore;
 6 
 7 public class CyclicBarrierTest {
 8 
 9     public static void main(String[] args) {
10         ExecutorService service = Executors.newCachedThreadPool();
11         //final  CyclicBarrier cb = new CyclicBarrier(3);//建立CyclicBarrier對象並設置3個公共屏障點
12         final  CyclicBarrier cb = new CyclicBarrier(3,new Runnable(){
13             @Override
14             public void run() {
15                 System.out.println("********我最早執行***********");
16             }
17         });
18         for(int i=0;i<3;i++){
19             Runnable runnable = new Runnable(){
20                     public void run(){
21                     try {
22                         Thread.sleep((long)(Math.random()*10000));    
23                         System.out.println("線程" + Thread.currentThread().getName() + 
24                                 "即將到達集合地點1,當前已有" + cb.getNumberWaiting() + "個已經到達,正在等候");                        
25                         cb.await();//到此若是沒有達到公共屏障點,則該線程處於等待狀態,若是達到公共屏障點則全部處於等待的線程都繼續往下運行
26                         
27                         Thread.sleep((long)(Math.random()*10000));    
28                         System.out.println("線程" + Thread.currentThread().getName() + 
29                                 "即將到達集合地點2,當前已有" + cb.getNumberWaiting() + "個已經到達,正在等候");                        
30                         cb.await();    //這裏CyclicBarrier對象又能夠重用
31                         Thread.sleep((long)(Math.random()*10000));    
32                         System.out.println("線程" + Thread.currentThread().getName() + 
33                                 "即將到達集合地點3,當前已有" + cb.getNumberWaiting() + "個已經到達,正在等候");                        
34                         cb.await();                        
35                     } catch (Exception e) {
36                         e.printStackTrace();
37                     }                
38                 }
39             };
40             service.execute(runnable);
41         }
42         service.shutdown();
43     }
44 }

複製代碼

則結果以下:ide

複製代碼

線程pool-1-thread-1即將到達集合地點1,當前已有0個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點1,當前已有1個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點1,當前已有2個已經到達,正在等候
********我最早執行***********
線程pool-1-thread-1即將到達集合地點2,當前已有0個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點2,當前已有1個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點2,當前已有2個已經到達,正在等候
********我最早執行***********
線程pool-1-thread-1即將到達集合地點3,當前已有0個已經到達,正在等候
線程pool-1-thread-3即將到達集合地點3,當前已有1個已經到達,正在等候
線程pool-1-thread-2即將到達集合地點3,當前已有2個已經到達,正在等候
********我最早執行***********

複製代碼

相關文章
相關標籤/搜索