導(dǎo)語
"路漫漫其修遠(yuǎn)兮,吾將上下而求索",最近在閱讀鴻洋大神的博客時(shí)看到了java并發(fā)編程專題之閉鎖CountDownLatch,自己也跟著寫了寫。最近發(fā)現(xiàn)剛學(xué)過的東西只要長時(shí)間不用就忘得一干二凈,所以日常筆記予以記錄,以便日后翻閱。
CountDownLatch是java中一個(gè)同步工具類,它允許一個(gè)或多個(gè)線程一直等待,直到其他線程的操作執(zhí)行完后在執(zhí)行。CountDownLatch在java1.5被引入,這個(gè)類能夠使一個(gè)線程等待其他線程完成自己的工作后再執(zhí)行,比如:應(yīng)用程序的主線程希望子線程在完成框架的啟動(dòng)任務(wù)后再執(zhí)行。
一. 基本原理
CountDownLatch是使用計(jì)數(shù)器來完成線程的等待,計(jì)數(shù)器的初始值為待完成的線程數(shù)。每當(dāng)一個(gè)線程完成自己任務(wù)后,計(jì)數(shù)器就會(huì)減一,當(dāng)計(jì)數(shù)器減為零時(shí),表示所有線程已完成自己的任務(wù),閉鎖等待的線程就會(huì)恢復(fù)執(zhí)行任務(wù)。

二.使用示例
模擬場景:一家三口約定下班后去XXX飯店一起吃飯,但是他們上班的地點(diǎn)不同,遠(yuǎn)近也不同。所以先到飯店的需要等待其他家庭成員全部到齊后才一起開動(dòng)。
- 1 抽象類Dinner實(shí)現(xiàn)了Runnable接口,重寫run方法模擬到飯店的過程,定義抽象方法setSpeed()模擬到達(dá)飯店的時(shí)間。
- 2 Father、Mother、Son繼承了Dinner類并重寫了setSpeed方法。
- 3 主線程中初始化閉鎖CountDownLatch、執(zhí)行器Exetor、3個(gè)Dinner對象,并在3個(gè)線程執(zhí)行后開始等待其他線程執(zhí)行完畢。
Dinner.java
public abstract class Dinner implements Runnable {
private String name;
private CountDownLatch mLatch;
public Dinner(String name, CountDownLatch latch) {
this.name = name;
this.mLatch = latch;
}
@Override
public void run() {
setSpeed();
System.out.println(getName() + "到達(dá)餐館!");
mLatch.countDown();
}
public String getName() {
return this.name;
}
public abstract void setSpeed();
}
Father.java
public class father extends Dinner {
public father(String name, CountDownLatch latch) {
super(name, latch);
}
@Override
public void setSpeed() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
其他的Mother.java 、Son.java也是繼承了Dinner類,只是在SetSpeed中線程休眠的時(shí)間不同。
主線程Main
CountDownLatchTest.java
public class CountDownLatchTest {
public static void main(String[] args) {
System.out.println("出發(fā)去餐館...");
CountDownLatch downLatch = new CountDownLatch(3);
Executor executor = Executors.newFixedThreadPool(3);
Dinner father = new father("father", downLatch);
Dinner mother = new Mother("mother", downLatch);
Dinner son = new Son("son", downLatch);
executor.execute(son);
executor.execute(mother);
executor.execute(father);
try {
downLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("全部到達(dá)餐館");
}
}
運(yùn)行結(jié)果:

可以看到,當(dāng)主線程執(zhí)行await方法等待其他線程全部執(zhí)行完畢。
三. 結(jié)束語
本文純屬個(gè)人經(jīng)驗(yàn)及觀點(diǎn),如有錯(cuò)誤歡迎指正、交流。?