從名字可以看出,CountDownLatch是一個倒數(shù)計數(shù)的鎖,當?shù)箶?shù)到0時觸發(fā)事件,也就是開鎖,其他人就可以進入了。在一些應用場合中,需要等待某個條件達到要求后才能做后面的事情;同時當線程都完成后也會觸發(fā)事件,以便進行后面的操作。
CountDownLatch最重要的方法是countDown()和await(),前者主要是倒數(shù)一次,后者是等待倒數(shù)到0,如果沒有到達0,就只有阻塞等待了。
一個CountDouwnLatch實例是不能重復使用的,也就是說它是一次性的,鎖一經(jīng)被打開就不能再關閉使用了,如果想重復使用,請考慮使用CyclicBarrier。
下面的例子簡單的說明了CountDownLatch的使用方法,模擬了100米賽跑,10名選手已經(jīng)準備就緒,只等裁判一聲令下。當所有人都到達終點時,比賽結束。
同樣,線程池需要顯式shutdown。
package concurrent;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;
public class TestCountDownLatch { public static void main(String[] args) throws InterruptedException { // 開始的倒數(shù)鎖 final CountDownLatch begin = new CountDownLatch(1); // 結束的倒數(shù)鎖 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.countDown(); } } }; exec.submit(run); } System.out.println("Game Start"); begin.countDown(); end.await(); System.out.println("Game Over"); exec.shutdown(); } } |
運行結果:
Game Start
No.4 arrived
No.1 arrived
No.7 arrived
No.9 arrived
No.3 arrived
No.2 arrived
No.8 arrived
No.10 arrived
No.6 arrived
No.5 arrived
Game Over