CountDownLatch概念
CountDownLatch又被稱為倒計(jì)時(shí)鎖凯砍,它是一個(gè)同步輔助類蓬衡,它允許一個(gè)或多個(gè)線程一直等待直到其他線程執(zhí)行完畢才開始執(zhí)行唇礁。用給定的計(jì)數(shù)初始化CountDownLatch,其含義是要被等待執(zhí)行完的線程個(gè)數(shù)路鹰。每次調(diào)用CountDown()贷洲,計(jì)數(shù)減1。
主程序執(zhí)行到await()函數(shù)會(huì)阻塞等待線程的執(zhí)行晋柱,直到計(jì)數(shù)為0
我們來看下它的方法优构。
public CountDownLatch(int count); //指定計(jì)數(shù)的次數(shù),只能被設(shè)置1次
public void countDown(); //調(diào)用此方法則計(jì)數(shù)減1
public void await() throws InterruptedException //調(diào)用此方法會(huì)一直阻塞當(dāng)前線程雁竞,直到計(jì)時(shí)器的值為0钦椭,除非線程被中斷。
Public Long getCount(); //得到當(dāng)前的計(jì)數(shù)
Public boolean await(long timeout, TimeUnit unit) //調(diào)用此方法會(huì)一直阻塞當(dāng)前線程碑诉,直到計(jì)時(shí)器的值為0彪腔,除非線程被中斷或者計(jì)數(shù)器超時(shí),返回false代表計(jì)數(shù)器超時(shí)进栽。
CountDownLatch實(shí)例
模擬10人賽跑德挣。10人跑完后才喊"Game Over."
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class CountDownLatchTest {
private static final int RUNNER_COUNT = 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 i = 0; i < RUNNER_COUNT; i++) {
final int NO = i + 1;
//從1號(hào)到10號(hào)線程都在這里被建立
Runnable run = new Runnable() {
@Override
public void run() {
try {
//所有線程阻塞在這里,等待槍響
begin.await();
//每個(gè)人跑完的時(shí)間
Thread.sleep((long)(Math.random() * 10000));
System.out.println("No." + NO + " arrived");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//每跑完一個(gè)人快毛,倒計(jì)時(shí)鎖減一
end.countDown();//(倒計(jì)時(shí)鎖被減一)
}
}
};
exec.submit(run);
}
System.out.println("Game Start ...");
//槍響
begin.countDown();//倒計(jì)時(shí)鎖被解除減一(begin解除)
//等待所有人跑完
end.await();//倒計(jì)時(shí)鎖沒有被解除之前盲厌,將被阻塞在這里
end.await(30, TimeUnit.SECONDS);
System.out.println("Game Over.");
exec.shutdown();
}
}
輸出
Game Start ...
No.6 arrived
No.4 arrived
No.10 arrived
No.3 arrived
No.9 arrived
No.5 arrived
No.8 arrived
No.7 arrived
No.1 arrived
No.2 arrived
Game Over.
CountDownLatch與join的區(qū)別
調(diào)用join方法需要等待thread執(zhí)行完畢才能繼續(xù)向下執(zhí)行,而CountDownLatch只需要檢查計(jì)數(shù)器的值為零就可以繼續(xù)向下執(zhí)行,相比之下祸泪,CountDownLatch更加靈活一些,可以實(shí)現(xiàn)一些更加復(fù)雜的業(yè)務(wù)場景建芙。
面試題
(1)解釋一下CountDownLatch概念?
(2)CountDownLatch 和CyclicBarrier的不同之處?
(3)給出一些CountDownLatch使用的例子?
(4) CountDownLatch 類中主要的方法?