Java之CountDownLatch使用
CountDownLatch
1、類介紹
一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。用給定的計數 初始化 CountDownLatch。由於調用了 countDown() 方法,所以在當前計數到達零之前,await 方法會一直受阻塞。之後,會釋放所有等待的線程,await 的所有後續調用都將立即返回。這種現象只出現一次——計數無法被重置。 一個線程(或者多個), 等待另外N個線程完成某個事情之後才能執行
countDown
public void countDown()
- 遞減鎖存器的計數,如果計數到達零,則釋放所有等待的線程。如果當前計數大於零,則將計數減少。如果新的計數爲零,出於線程調度目的,將重新啓用所有的等待線程。
如果當前計數等於零,則不發生任何操作。
await
public boolean await(long timeout, TimeUnit unit) throws InterruptedException
- 使當前線程在鎖存器倒計數至零之前一直等待,除非線程被中斷或超出了指定的等待時間。如果當前計數爲零,則此方法立刻返回
true
值。如果當前計數大於零,則出於線程調度目的,將禁用當前線程,且在發生以下三種情況之一前,該線程將一直處於休眠狀態:
- 由於調用
countDown()
方法,計數到達零;或者 - 其他某個線程中斷當前線程;或者
- 已超出指定的等待時間。
如果計數到達零,則該方法返回
true
值。如果當前線程:
- 在進入此方法時已經設置了該線程的中斷狀態;或者
- 在等待時被中斷,
則拋出
InterruptedException
,並且清除當前線程的已中斷狀態。如果超出了指定的等待時間,則返回值爲false
。如果該時間小於等於零,則此方法根本不會等待。 - 由於調用
-
- 參數:
timeout
- 要等待的最長時間unit
-timeout
參數的時間單位。- 返回:
- 如果計數到達零,則返回
true
;如果在計數到達零之前超過了等待時間,則返回false
- 拋出:
InterruptedException
- 如果當前線程在等待時被中斷
4、相關實例
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();
}
}
5、輸出結果Game
Start
No.9 arrived
No.6 arrived
No.8 arrived
No.7 arrived
No.10 arrived
No.1 arrived
No.5 arrived
No.4 arrived
No.2 arrived
No.3 arrived
Game Over