深耕 JDK 源碼 - CountDownLatch

多線程編程中凳寺,線程之間的協(xié)同與同步是一種常見的需求。Java 提供了許多用于實(shí)現(xiàn)線程同步的工具彤侍,其中之一就是 CountDownLatch肠缨。CountDownLatch 是一個(gè)簡單而強(qiáng)大的多線程同步工具,可以幫助開發(fā)者實(shí)現(xiàn)一組線程在某個(gè)事件完成后再同時(shí)執(zhí)行的需求盏阶。本文將詳細(xì)介紹 CountDownLatch 的實(shí)現(xiàn)原理晒奕、用法以及相關(guān)的代碼解釋。

一名斟、實(shí)現(xiàn)原理

CountDownLatch 內(nèi)部維護(hù)了一個(gè)計(jì)數(shù)器脑慧,通過其構(gòu)造方法指定初始計(jì)數(shù)值。計(jì)數(shù)器的值在 CountDownLatch 對象創(chuàng)建后是不可修改的砰盐。每當(dāng)一個(gè)線程完成了某個(gè)任務(wù)時(shí)闷袒,可以調(diào)用 CountDownLatch 的 countDown() 方法,將計(jì)數(shù)值減一楞卡。當(dāng)計(jì)數(shù)值變?yōu)榱銜r(shí)霜运,所有在 CountDownLatch 上等待的線程會(huì)被喚醒,可以繼續(xù)執(zhí)行蒋腮。

CountDownLatch 的實(shí)現(xiàn)原理可以簡單描述如下:

  1. 創(chuàng)建 CountDownLatch 對象時(shí),需要指定初始計(jì)數(shù)值藕各。
  2. 每個(gè)線程在完成任務(wù)后池摧,通過調(diào)用 countDown() 方法將計(jì)數(shù)值減一。
  3. 當(dāng)計(jì)數(shù)值變?yōu)榱銜r(shí)激况,所有等待的線程會(huì)被喚醒作彤,可以繼續(xù)執(zhí)行后續(xù)的邏輯。

二乌逐、用法

CountDownLatch 常用于一組線程中竭讳,有一個(gè)或多個(gè)線程需要等待其他線程完成某個(gè)任務(wù)后再繼續(xù)執(zhí)行。以下是 CountDownLatch 的一般用法:

  1. 創(chuàng)建 CountDownLatch 對象浙踢,并指定初始計(jì)數(shù)值:
CountDownLatch latch = new CountDownLatch(3); // 初始計(jì)數(shù)值為 3

這里創(chuàng)建了一個(gè) CountDownLatch 對象 latch绢慢,并指定初始計(jì)數(shù)值為 3。

  1. 創(chuàng)建需要等待的線程洛波,并在其任務(wù)完成后調(diào)用 countDown() 方法:
// 線程1
Thread thread1 = new Thread(() -> {
    // 執(zhí)行任務(wù)
    latch.countDown(); // 計(jì)數(shù)值減一
});

// 線程2
Thread thread2 = new Thread(() -> {
    // 執(zhí)行任務(wù)
    latch.countDown(); // 計(jì)數(shù)值減一
});

// 線程3
Thread thread3 = new Thread(() -> {
    // 執(zhí)行任務(wù)
    latch.countDown(); // 計(jì)數(shù)值減一
});

這里創(chuàng)建了三個(gè)線程 thread1胰舆、thread2、thread3蹬挤,并在其任務(wù)完成后分別調(diào)用了 countDown() 方法缚窿,將計(jì)數(shù)值減一。

  1. 創(chuàng)建需要等待的線程焰扳,并在其任務(wù)完成后調(diào)用 await() 方法來等待其他線程完成任務(wù):
// 等待線程1倦零、線程2误续、線程3完成任務(wù)
try {
    latch.await(); // 等待計(jì)數(shù)值變?yōu)榱?} catch (InterruptedException e) {
    // 處理中斷異常
}

這里調(diào)用了 await() 方法,它會(huì)阻住當(dāng)前線程扫茅,直到計(jì)數(shù)值變?yōu)榱闾G叮此械却木€程都完成了任務(wù)。

  1. 完整示例代碼:

下面是一個(gè)完整的示例代碼诞帐,演示了 CountDownLatch 的使用:

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {

    public static void main(String[] args) {
        // 創(chuàng)建 CountDownLatch 對象欣尼,并指定初始計(jì)數(shù)值為 3
        CountDownLatch latch = new CountDownLatch(3);

        // 創(chuàng)建線程1
        Thread thread1 = new Thread(() -> {
            System.out.println("Thread 1 is running...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread 1 finished.");
            latch.countDown(); // 計(jì)數(shù)值減一
        });

        // 創(chuàng)建線程2
        Thread thread2 = new Thread(() -> {
            System.out.println("Thread 2 is running...");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread 2 finished.");
            latch.countDown(); // 計(jì)數(shù)值減一
        });

        // 創(chuàng)建線程3
        Thread thread3 = new Thread(() -> {
            System.out.println("Thread 3 is running...");
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread 3 finished.");
            latch.countDown(); // 計(jì)數(shù)值減一
        });

        // 啟動(dòng)線程
        thread1.start();
        thread2.start();
        thread3.start();

        try {
            latch.await(); // 等待計(jì)數(shù)值變?yōu)榱?            System.out.println("All threads finished. Proceeding to next step.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

運(yùn)行以上代碼,會(huì)輸出類似以下的結(jié)果:

Thread 3 is running...
Thread 1 is running...
Thread 2 is running...
Thread 3 finished.
Thread 1 finished.
Thread 2 finished.
All threads finished. Proceeding to next step.

三停蕉、總結(jié)

CountDownLatch 是一個(gè)簡單而強(qiáng)大的多線程同步工具愕鼓,可以幫助開發(fā)者實(shí)現(xiàn)一組線程在某個(gè)事件完成后再同時(shí)執(zhí)行的需求。它的實(shí)現(xiàn)原理簡單明了慧起,通過維護(hù)一個(gè)計(jì)數(shù)器來實(shí)現(xiàn)線程之間的同步菇晃。通過調(diào)用 countDown() 方法將計(jì)數(shù)值減一,當(dāng)計(jì)數(shù)值變?yōu)榱銜r(shí)蚓挤,所有等待的線程會(huì)被喚醒磺送。CountDownLatch 在實(shí)際開發(fā)中可以應(yīng)用于各種場景,例如等待多個(gè)線程完成初始化灿意、等待多個(gè)線程同時(shí)開始執(zhí)行某個(gè)任務(wù)等估灿。使用 CountDownLatch 可以使多線程編程更加簡潔、高效和安全缤剧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末馅袁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子荒辕,更是在濱河造成了極大的恐慌汗销,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抵窒,死亡現(xiàn)場離奇詭異弛针,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)李皇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門削茁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人疙赠,你說我怎么就攤上這事付材。” “怎么了圃阳?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵厌衔,是天一觀的道長。 經(jīng)常有香客問我捍岳,道長富寿,這世上最難降的妖魔是什么睬隶? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮页徐,結(jié)果婚禮上苏潜,老公的妹妹穿的比我還像新娘。我一直安慰自己变勇,他們只是感情好恤左,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著搀绣,像睡著了一般飞袋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上链患,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天巧鸭,我揣著相機(jī)與錄音,去河邊找鬼麻捻。 笑死纲仍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贸毕。 我是一名探鬼主播郑叠,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼明棍!你這毒婦竟也來了锻拘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤击蹲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后婉宰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體歌豺,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年心包,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了类咧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,498評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蟹腾,死狀恐怖痕惋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情娃殖,我是刑警寧澤值戳,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站炉爆,受9級特大地震影響堕虹,放射性物質(zhì)發(fā)生泄漏卧晓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一赴捞、第九天 我趴在偏房一處隱蔽的房頂上張望逼裆。 院中可真熱鬧,春花似錦赦政、人聲如沸胜宇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桐愉。三九已至,卻和暖如春然评,著一層夾襖步出監(jiān)牢的瞬間仅财,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工碗淌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盏求,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓亿眠,卻偏偏與公主長得像碎罚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子纳像,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評論 2 359