JavaTM 2 Platform
Standard Ed. 6

java.util.concurrent
類別 CountDownLatch

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

public class CountDownLatch
extends Object

一個同步輔助類別,在完成一組正在其他執行緒中執行的操作之前,它允許一個或多個執行緒一直等待。

用給定的計數 初始化 CountDownLatch。由於調用了 countDown() 方法,所以在當前計數到達零之前,await 方法會一直受阻塞。之後,會釋放所有等待的執行緒,await 的所有後續調用都將立即返回。這種現象只出現一次——計數無法被重置。如果需要重置計數,請考慮使用 CyclicBarrier

CountDownLatch 是一個通用同步工具,它有很多用途。將計數 1 初始化的 CountDownLatch 用作一個簡單的開/關鎖存器,或入口:在通過調用 countDown() 的執行緒打開入口前,所有調用 await 的執行緒都一直在入口處等待。用 N 初始化的 CountDownLatch 可以使一個執行緒在 N 個執行緒完成某項操作之前一直等待,或者使其在某項操作完成 N 次之前一直等待。

CountDownLatch 的一個有用特性是,它不要求調用 countDown 方法的執行緒等到計數到達零時才繼續,而在所有執行緒都能通過之前,它只是阻止任何執行緒繼續通過一個 await

範例用法: 下面給出了兩個類別,其中一組 worker 執行緒使用了兩個倒計數鎖存器:

 class Driver { // ...
   void main() throws InterruptedException {
     CountDownLatch startSignal = new CountDownLatch(1);
     CountDownLatch doneSignal = new CountDownLatch(N);

     for (int i = 0; i < N; ++i) // create and start threads
       new Thread(new Worker(startSignal, doneSignal)).start();

     doSomethingElse();            // don't let run yet
     startSignal.countDown();      // let all threads proceed
     doSomethingElse();
     doneSignal.await();           // wait for all to finish
   }
 }

 class Worker implements Runnable {
   private final CountDownLatch startSignal;
   private final CountDownLatch doneSignal;
   Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
      this.startSignal = startSignal;
      this.doneSignal = doneSignal;
   }
   public void run() {
      try {
        startSignal.await();
        doWork();
        doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }

 

另一種典型用法是,將一個問題分成 N 個部分,用執行每個部分並讓鎖存器倒計數的 Runnable 來描述每個部分,然後將所有 Runnable 加入到 Executor 佇列。當所有的子部分完成後,協調執行緒就能夠通過 await。(當執行緒必須用這種方法反覆倒計數時,可改為使用 CyclicBarrier。)

 class Driver2 { // ...
   void main() throws InterruptedException {
     CountDownLatch doneSignal = new CountDownLatch(N);
     Executor e = ...

     for (int i = 0; i < N; ++i) // create and start threads
       e.execute(new WorkerRunnable(doneSignal, i));

     doneSignal.await();           // wait for all to finish
   }
 }

 class WorkerRunnable implements Runnable {
   private final CountDownLatch doneSignal;
   private final int i;
   WorkerRunnable(CountDownLatch doneSignal, int i) {
      this.doneSignal = doneSignal;
      this.i = i;
   }
   public void run() {
      try {
        doWork(i);
        doneSignal.countDown();
      } catch (InterruptedException ex) {} // return;
   }

   void doWork() { ... }
 }

 

記憶體一致性效果:執行緒中調用 countDown() 之前的操作 happen-before 緊跟在從另一個執行緒中對應 await() 成功返回的操作。

從以下版本開始:
1.5

建構子摘要
CountDownLatch(int count)
          建構一個用給定計數初始化的 CountDownLatch
 
方法摘要
 void await()
          使當前執行緒在鎖存器倒計數至零之前一直等待,除非執行緒被中斷
 boolean await(long timeout, TimeUnit unit)
          使當前執行緒在鎖存器倒計數至零之前一直等待,除非執行緒被中斷或超出了指定的等待時間。
 void countDown()
          遞減鎖存器的計數,如果計數到達零,則釋放所有等待的執行緒。
 long getCount()
          返回當前計數。
 String toString()
          返回標識此鎖存器及其狀態的字元串。
 
從類別 java.lang.Object 繼承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

建構子詳細資訊

CountDownLatch

public CountDownLatch(int count)
建構一個用給定計數初始化的 CountDownLatch

參數:
count - 在執行緒能通過 await() 之前,必須調用 countDown() 的次數
拋出:
IllegalArgumentException - 如果 count 為負
方法詳細資訊

await

public void await()
           throws InterruptedException
使當前執行緒在鎖存器倒計數至零之前一直等待,除非執行緒被中斷

如果當前計數為零,則此方法立即返回。

如果當前計數大於零,則出於執行緒排程目的,將禁用當前執行緒,且在發生以下兩種情況之一前,該執行緒將一直處於休眠狀態:

如果當前執行緒:

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

拋出:
InterruptedException - 如果當前執行緒在等待時被中斷

await

public boolean await(long timeout,
                     TimeUnit unit)
              throws InterruptedException
使當前執行緒在鎖存器倒計數至零之前一直等待,除非執行緒被中斷或超出了指定的等待時間。

如果當前計數為零,則此方法立刻返回 true 值。

如果當前計數大於零,則出於執行緒排程目的,將禁用當前執行緒,且在發生以下三種情況之一前,該執行緒將一直處於休眠狀態:

如果計數到達零,則該方法返回 true 值。

如果當前執行緒:

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

如果超出了指定的等待時間,則返回值為 false。如果該時間小於等於零,則此方法根本不會等待。

參數:
timeout - 要等待的最長時間
unit - timeout 參數的時間單位。
返回:
如果計數到達零,則返回 true;如果在計數到達零之前超過了等待時間,則返回 false
拋出:
InterruptedException - 如果當前執行緒在等待時被中斷

countDown

public void countDown()
遞減鎖存器的計數,如果計數到達零,則釋放所有等待的執行緒。

如果當前計數大於零,則將計數減少。如果新的計數為零,出於執行緒排程目的,將重新啟用所有的等待執行緒。

如果當前計數等於零,則不發生任何操作。


getCount

public long getCount()
返回當前計數。

此方法通常用於除錯和測試。

返回:
當前計數

toString

public String toString()
返回標識此鎖存器及其狀態的字元串。狀態用括號括起來,包括字元串 "Count =",後跟當前計數。

覆寫:
類別 Object 中的 toString
返回:
標識此鎖存器及其狀態的字元串

JavaTM 2 Platform
Standard Ed. 6

提交錯誤或意見

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