CyclicBarrier

1、類說明:

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

2、使用場景:

需要所有的子任務都完成時,才執行主任務,這個時候就可以選擇使用CyclicBarrier。

3、常用方法:

await

public int await()
          throws InterruptedException,
                 BrokenBarrierException
在所有參與者都已經在此 barrier 上調用 await方法之前,將一直等待。如果當前線程不是將到達的最後一個線程,出於調度目的,將禁用它,且在發生以下情況之一前,該線程將一直處於休眠狀態:

  • 最後一個線程到達;或者
  • 其他某個線程中斷當前線程;或者
  • 其他某個線程中斷另一個等待線程;或者
  • 其他某個線程在等待 barrier 時超時;或者
  • 其他某個線程在此 barrier 上調用 reset()

如果當前線程:

  • 在進入此方法時已經設置了該線程的中斷狀態;或者
  • 在等待時被中斷

則拋出 InterruptedException,並且清除當前線程的已中斷狀態。如果在線程處於等待狀態時 barrier 被 reset(),或者在調用 await 時 barrier 被損壞,抑或任意一個線程正處於等待狀態,則拋出 BrokenBarrierException 異常。

如果任何線程在等待時被 中斷,則其他所有等待線程都將拋出 BrokenBarrierException 異常,並將 barrier 置於損壞狀態。

如果當前線程是最後一個將要到達的線程,並且構造方法中提供了一個非空的屏障操作,則在允許其他線程繼續運行之前,當前線程將運行該操作。如果在執行屏障操作過程中發生異常,則該異常將傳播到當前線程中,並將 barrier 置於損壞狀態。

 

返回:
到達的當前線程的索引,其中,索引 getParties() - 1 指示將到達的第一個線程,零指示最後一個到達的線程
拋出:
InterruptedException - 如果當前線程在等待時被中斷
BrokenBarrierException - 如果另一個 線程在當前線程等待時被中斷或超時,或者重置了 barrier,或者在調用 await 時 barrier 被損壞,抑或由於異常而導致屏障操作(如果存在)失敗。
4、相關實例

賽跑時,等待所有人都準備好時,才起跑:

<pre name="code" class="java">public class CountDownLatchTest {

    // 模擬了100米賽跑,10名選手已經準備就緒,只等裁判一聲令下。當所有人都到達終點時,比賽結束。
    public static void main(String[] args) throws InterruptedException {

        // 開始的倒數鎖 
        final CountDownLatch begin = new CountDownLatch(1);  

        // 結束的倒數鎖 
        final CountDownLatch end = new CountDownLatch(10);  

        // 十名選手 
        final ExecutorService exec = Executors.newFixedThreadPool(10);  

        for (int index = 0; index < 10; index++) {
            final int NO = index + 1;  
            Runnable run = new Runnable() {
                public void run() {  
                    try {  
                        // 如果當前計數爲零,則此方法立即返回。
                        // 等待
                        begin.await();  
                        Thread.sleep((long) (Math.random() * 10000));  
                        System.out.println("No." + NO + " arrived");  
                    } catch (InterruptedException e) {  
                    } finally {  
                        // 每個選手到達終點時,end就減一
                        end.countDown();
                    }  
                }  
            };  
            exec.submit(run);
        }  
        System.out.println("Game Start");  
        // begin減一,開始遊戲
        begin.countDown();  
        // 等待end變爲0,即所有選手到達終點
        end.await();  
        System.out.println("Game Over");  
        exec.shutdown();  
    }
}


輸出結果:
3號選手 準備好了...
2號選手 準備好了...
1號選手 準備好了...
1號選手 起跑!
2號選手 起跑!
3號選手 起跑!
轉載地址:http://www.itzhai.com/the-introduction-and-use-of-cyclicbarrier.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章