CountDownLatch類位于java.util.concurrent包下,利用它可以實作類似計數器的功能。CountDownLatch的一個非常典型的應用場景是:有一個任務想要往下執行,但必須要等到其他的任務執行完畢後才可以繼續往下執行。假如我們這個想要繼續往下執行的任務調用一個CountDownLatch對象的await()方法,其他的任務執行完自己的任務後調用同一個CountDownLatch對象上的countDown()方法,這個調用await()方法的任務将一直阻塞等待,直到這個CountDownLatch對象的計數值減到0為止。
CountDownLatch類隻提供了一個構造器:
public CountDownLatch(int count) { }; //參數count為計數值
下面這3個方法是CountDownLatch類中最重要的方法:
public void await() throws InterruptedException { }; //調用await()方法的線程會被挂起,它會等待直到count值為0才繼續執行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { }; //和await()類似,隻不過等待一定的時間後count值還沒變為0的話就會繼續執行
public void countDown() { }; //将count值減1
CountDownLatch的用法示例:
//一個CountDouwnLatch執行個體是不能重複使用的,也就是說它是一次性的,鎖一經被打開就不能再關閉使用了,如果想重複使用,請考慮使用CyclicBarrier。
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 {
// 如果目前計數為零,則此方法立即傳回。
// 等待
System.out.println("await before====="+NO);
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();
}
}