JavaTM 2 Platform
Standard Ed. 6

java.util.concurrent
類別 CyclicBarrier

java.lang.Object
  繼承者 java.util.concurrent.CyclicBarrier

public class CyclicBarrier
extends Object

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

CyclicBarrier 支持一個可選的 Runnable 命令,在一組執行緒中的最後一個執行緒到達之後(但在釋放所有執行緒之前),該命令只在每個屏障點運行一次。若在繼續所有參與執行緒之前更新共享狀態,此屏障操作 很有用。

範例用法:下面是一個在並行分解設計中使用 barrier 的例子:

 class Solver {
   final int N;
   final float[][] data;
   final CyclicBarrier barrier;
   
   class Worker implements Runnable {
     int myRow;
     Worker(int row) { myRow = row; }
     public void run() {
       while (!done()) {
         processRow(myRow);

         try {
           barrier.await(); 
         } catch (InterruptedException ex) { 
return; 
         } catch (BrokenBarrierException ex) { 
return; 
         }
       }
     }
   }

   public Solver(float[][] matrix) {
     data = matrix;
     N = matrix.length;
     barrier = new CyclicBarrier(N, 
                                 new Runnable() {
                                   public void run() { 
                                     mergeRows(...); 
                                   }
                                 });
     for (int i = 0; i < N; ++i) 
       new Thread(new Worker(i)).start();

     waitUntilDone();
   }
 }
 
在這個例子中,每個 worker 執行緒處理矩陣的一行,在處理完所有的行之前,該執行緒將一直在屏障處等待。處理完所有的行之後,將執行所提供的 Runnable 屏障操作,併合並這些行。如果合併者確定已經找到了一個解決方案,那麼 done() 將返回 true,所有的 worker 執行緒都將終止。

如果屏障操作在執行時不依賴於正掛起的執行緒,則執行緒組中的任何執行緒在獲得釋放時都能執行該操作。為方便此操作,每次調用 await() 都將返回能到達屏障處的執行緒的索引。然後,您可以選擇哪個執行緒應該執行屏障操作,例如:

  if (barrier.await() == 0) {
     // log the completion of this iteration
   }

對於失敗的同步嘗試,CyclicBarrier 使用了一種要麼全部要麼全不 (all-or-none) 的破壞網要:如果因為中斷、失敗或者逾時等原因,導致執行緒過早地離開了屏障點,那麼在該屏障點等待的其他所有執行緒也將通過 BrokenBarrierException(如果它們幾乎同時被中斷,則用 InterruptedException)以反常的方式離開。

記憶體一致性效果:執行緒中調用 await() 之前的操作 happen-before 那些是屏障操作的一部份的操作,後者依次 happen-before 緊跟在從另一個執行緒中對應 await() 成功返回的操作。

從以下版本開始:
1.5
另請參見:
CountDownLatch

建構子摘要
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()
          將屏障重置為其初始狀態。
 
從類別 java.lang.Object 繼承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

建構子詳細資訊

CyclicBarrier

public CyclicBarrier(int parties,
                     Runnable barrierAction)
創建一個新的 CyclicBarrier,它將在給定數量的參與者(執行緒)處於等待狀態時啟動,並在啟動 barrier 時執行給定的屏障操作,該操作由最後一個進入 barrier 的執行緒執行。

參數:
parties - 在啟動 barrier 前必須調用 await() 的執行緒數
barrierAction - 在啟動 barrier 時執行的命令;如果不執行任何操作,則該參數為 null
拋出:
IllegalArgumentException - 如果 parties 小於 1

CyclicBarrier

public CyclicBarrier(int parties)
創建一個新的 CyclicBarrier,它將在給定數量的參與者(執行緒)處於等待狀態時啟動,但它不會在啟動 barrier 時執行預定義的操作。

參數:
parties - 在啟動 barrier 前必須調用 await() 的執行緒數
拋出:
IllegalArgumentException - 如果 parties 小於 1
方法詳細資訊

getParties

public int getParties()
返回要求啟動此 barrier 的參與者數目。

返回:
要求啟動此 barrier 的參與者數目

await

public int await()
          throws InterruptedException,
                 BrokenBarrierException
在所有參與者都已經在此 barrier 上調用 await 方法之前,將一直等待。

如果當前執行緒不是將到達的最後一個執行緒,出於排程目的,將禁用它,且在發生以下情況之一前,該執行緒將一直處於休眠狀態:

如果當前執行緒:

則拋出 InterruptedException,並且清除當前執行緒的已中斷狀態。

如果在執行緒處於等待狀態時 barrier 被 reset(),或者在調用 await 時 barrier 被損壞,抑或任意一個執行緒正處於等待狀態,則拋出 BrokenBarrierException 異常。

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

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

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

await

public int await(long timeout,
                 TimeUnit unit)
          throws InterruptedException,
                 BrokenBarrierException,
                 TimeoutException
在所有參與者都已經在此屏障上調用 await 方法之前將一直等待,或者超出了指定的等待時間。

如果當前執行緒不是將到達的最後一個執行緒,出於排程目的,將禁用它,且在發生以下情況之一前,該執行緒將一直處於休眠狀態:

如果當前執行緒:

則拋出 InterruptedException,並且清除當前執行緒的已中斷狀態。

如果超出指定的等待時間,則拋出 TimeoutException 異常。如果該時間小於等於零,則此方法根本不會等待。

如果在執行緒處於等待狀態時 barrier 被 reset(),或者在調用 await 時 barrier 被損壞,抑或任意一個執行緒正處於等待狀態,則拋出 BrokenBarrierException 異常。

如果任何執行緒在等待時被中斷,則其他所有等待執行緒都將拋出 BrokenBarrierException,並將屏障置於損壞狀態。

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

參數:
timeout - 等待 barrier 的時間
unit - 逾時參數的時間單位
返回:
到達的當前執行緒的索引,其中,索引 getParties() - 1 指示第一個將要到達的執行緒,零指示最後一個到達的執行緒
拋出:
InterruptedException - 如果當前執行緒在等待時被中斷
TimeoutException - 如果超出了指定的逾時時間
BrokenBarrierException - 如果另一個 執行緒在當前執行緒等待時被中斷或逾時,或者重置了 barrier,或者調用 await 時 barrier 被損壞,抑或由於異常而導致屏障操作(如果存在)失敗。

isBroken

public boolean isBroken()
查詢此屏障是否處於損壞狀態。

返回:
如果因為建構或最後一次重置而導致中斷或逾時,從而使一個或多個參與者擺脫此 barrier,或者因為異常而導致某個屏障操作失敗,則返回 true;否則返回 false

reset

public void reset()
將屏障重置為其初始狀態。如果所有參與者目前都在屏障處等待,則它們將返回,同時拋出一個 BrokenBarrierException。注意,在由於其他原因造成損壞之後,實行重置可能會變得很複雜;此時需要使用其他方式重新同步執行緒,並選擇其中一個執行緒來執行重置。與為後續使用創建一個新 barrier 相比,這種方法可能更好一些。


getNumberWaiting

public int getNumberWaiting()
返回當前在屏障處等待的參與者數目。此方法主要用於除錯和斷言。

返回:
當前阻塞在 await() 中的參與者數目。

JavaTM 2 Platform
Standard Ed. 6

提交錯誤或意見

版權所有 2008 Sun Microsystems, Inc. 保留所有權利。請遵守GNU General Public License, version 2 only