CyclicBarrier的用法


  CyclicBarrier是一個同步輔助類,它允許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。在涉及一組固定大小的線程的程序中,這些線程必須不時地互相等待,此時 CyclicBarrier 很有用。因為該 barrier 在釋放等待線程后可以重用,所以稱它為循環 的 barrier。

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

構造方法摘要
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。如果把上面的例子改成下面這樣:

 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 }

則結果如下:

線程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個已經到達,正在等候
********我最先執行***********


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM