日常筆記—CountDownLatch

導(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ù)。

CountDownLatch基本原理圖.png

二.使用示例

模擬場景:一家三口約定下班后去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é)果:


result.png

可以看到,當(dāng)主線程執(zhí)行await方法等待其他線程全部執(zhí)行完畢。

三. 結(jié)束語

本文純屬個(gè)人經(jīng)驗(yàn)及觀點(diǎn),如有錯(cuò)誤歡迎指正、交流。?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容