CountDownLatch與thread.join()的區(qū)別

今天學(xué)習(xí)CountDownLatch這個類佑菩,作用感覺和join很像扁凛,然后就百度了一下忍疾,看了他們之間的區(qū)別。所以在此記錄一下谨朝。

首先來看一下join卤妒,在當(dāng)前線程中,如果調(diào)用某個thread的join方法字币,那么當(dāng)前線程就會被阻塞则披,直到thread線程執(zhí)行完畢,當(dāng)前線程才能繼續(xù)執(zhí)行洗出。join的原理是士复,不斷的檢查thread是否存活,如果存活,那么讓當(dāng)前線程一直wait阱洪,直到thread線程終止便贵,線程的this.notifyAll 就會被調(diào)用。

我們來看一下這個應(yīng)用場景:假設(shè)現(xiàn)在公司有三個員工A,B,C冗荸,他們要開會承璃。但是A需要等B,C準(zhǔn)備好之后再才能開始,B,C需要同時準(zhǔn)備蚌本。我們先用join模擬上面的場景盔粹。

Employee.java:

public class Employee extends Thread{
        
    private String employeeName;
    
    private long time;

    public Employee(String employeeName,long time){
        this.employeeName = employeeName;
        this.time = time;
    }
    
    @Override
    public void run() {
        try {
            System.out.println(employeeName+ "開始準(zhǔn)備");
            Thread.sleep(time);
            System.out.println(employeeName+" 準(zhǔn)備完成");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

JoinTest.java:

public class JoinTest {

    public static void main(String[] args) throws InterruptedException {
        Employee a = new Employee("A", 3000);
        Employee b = new Employee("B", 3000);
        Employee c = new Employee("C", 4000);
        
        b.start();
        c.start();
        
        b.join();
        c.join();
        System.out.println("B,C準(zhǔn)備完成");
        a.start();
    }
}

最后輸出結(jié)果如下:

C開始準(zhǔn)備
B開始準(zhǔn)備
B 準(zhǔn)備完成
C 準(zhǔn)備完成
B,C準(zhǔn)備完成
A開始準(zhǔn)備
A 準(zhǔn)備完成

可以看到,A總是在B,C準(zhǔn)備完成之后才開始執(zhí)行的。

CountDownLatch中我們主要用到兩個方法一個是await()方法程癌,調(diào)用這個方法的線程會被阻塞舷嗡,另外一個是countDown()方法,調(diào)用這個方法會使計數(shù)器減一嵌莉,當(dāng)計數(shù)器的值為0時进萄,因調(diào)用await()方法被阻塞的線程會被喚醒,繼續(xù)執(zhí)行烦秩。

接下來垮斯,我們用CountDownLatch來模擬一下郎仆。

Employee.java:

public class Employee extends Thread{

    private String employeeName;
    
    private long time;
    
    private CountDownLatch countDownLatch;

    public Employee(String employeeName,long time, CountDownLatch countDownLatch){
        this.employeeName = employeeName;
        this.time = time;
        this.countDownLatch = countDownLatch;
    }
    
    @Override
    public void run() {
        try {
            System.out.println(employeeName+ "開始準(zhǔn)備");
            Thread.sleep(time);
            System.out.println(employeeName+" 準(zhǔn)備完成");
            countDownLatch.countDown();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}

CountDownLatchTest.java:

public class CountDownLatchTest {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(2);
        Employee a = new Employee("A", 3000,countDownLatch);
        Employee b = new Employee("B", 3000,countDownLatch);
        Employee c = new Employee("C", 4000,countDownLatch);
        
        b.start();
        c.start();
        countDownLatch.await();
        System.out.println("B,C準(zhǔn)備完成");
        a.start();
    }
}

輸出結(jié)果如下:

B開始準(zhǔn)備
C開始準(zhǔn)備
B 準(zhǔn)備完成
C 準(zhǔn)備完成
B,C準(zhǔn)備完成
A開始準(zhǔn)備
A 準(zhǔn)備完成

上面可以看到只祠,CountDownLatch與join都能夠模擬上述的場景,那么他們有什么不同呢?這時候我們試想另外一個場景就能看到他們的區(qū)別了扰肌。

假設(shè)A抛寝,B,C的工作都分為兩個階段曙旭,A只需要等待B盗舰,C各自完成他們工作的第一個階段就可以執(zhí)行了。

我們來修改一下Employee類:

public class Employee extends Thread{

    private String employeeName;
    
    private long time;
    
    private CountDownLatch countDownLatch;

    public Employee(String employeeName,long time, CountDownLatch countDownLatch){
        this.employeeName = employeeName;
        this.time = time;
        this.countDownLatch = countDownLatch;
    }
    
    @Override
    public void run() {
        try {
            System.out.println(employeeName+ " 第一階段開始準(zhǔn)備");
            Thread.sleep(time);
            System.out.println(employeeName+" 第一階段準(zhǔn)備完成");
            
            countDownLatch.countDown();
            
            System.out.println(employeeName+ " 第二階段開始準(zhǔn)備");
            Thread.sleep(time);
            System.out.println(employeeName+" 第二階段準(zhǔn)備完成");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

CountDownLatchTest類不需要做修改桂躏,輸出結(jié)果入下:

B 第一階段開始準(zhǔn)備
C 第一階段開始準(zhǔn)備
B 第一階段準(zhǔn)備完成
B 第二階段開始準(zhǔn)備
C 第一階段準(zhǔn)備完成
C 第二階段開始準(zhǔn)備
B,C第一階段準(zhǔn)備完成
A 第一階段開始準(zhǔn)備
B 第二階段準(zhǔn)備完成
A 第一階段準(zhǔn)備完成
A 第二階段開始準(zhǔn)備
C 第二階段準(zhǔn)備完成
A 第二階段準(zhǔn)備完成

從結(jié)果可以看出钻趋,A在B,C第一階段準(zhǔn)備完成的時候就開始執(zhí)行了剂习,不需要等到第二階段準(zhǔn)備完成蛮位。這種場景下,用join是沒法實(shí)現(xiàn)的鳞绕。

總結(jié):調(diào)用join方法需要等待thread執(zhí)行完畢才能繼續(xù)向下執(zhí)行,而CountDownLatch只需要檢查計數(shù)器的值為零就可以繼續(xù)向下執(zhí)行失仁,相比之下,CountDownLatch更加靈活一些们何,可以實(shí)現(xiàn)一些更加復(fù)雜的業(yè)務(wù)場景萄焦。

個人博客:https://www.zhaojun.ink

參考:https://blog.csdn.net/zhutulang/article/details/48504487

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市冤竹,隨后出現(xiàn)的幾起案子拂封,更是在濱河造成了極大的恐慌茬射,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冒签,死亡現(xiàn)場離奇詭異躲株,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)镣衡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門霜定,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人廊鸥,你說我怎么就攤上這事望浩。” “怎么了惰说?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵磨德,是天一觀的道長。 經(jīng)常有香客問我吆视,道長典挑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任啦吧,我火速辦了婚禮您觉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘授滓。我一直安慰自己琳水,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布般堆。 她就那樣靜靜地躺著在孝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪淮摔。 梳的紋絲不亂的頭發(fā)上私沮,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音和橙,去河邊找鬼仔燕。 笑死,一個胖子當(dāng)著我的面吹牛胃碾,可吹牛的內(nèi)容都是我干的涨享。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼仆百,長吁一口氣:“原來是場噩夢啊……” “哼厕隧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤吁讨,失蹤者是張志新(化名)和其女友劉穎髓迎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體建丧,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡排龄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了翎朱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片橄维。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拴曲,靈堂內(nèi)的尸體忽然破棺而出争舞,到底是詐尸還是另有隱情,我是刑警寧澤澈灼,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布竞川,位于F島的核電站,受9級特大地震影響叁熔,放射性物質(zhì)發(fā)生泄漏委乌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一荣回、第九天 我趴在偏房一處隱蔽的房頂上張望遭贸。 院中可真熱鬧,春花似錦驹马、人聲如沸革砸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至册踩,卻和暖如春泳姐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背暂吉。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工胖秒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人慕的。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓阎肝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親肮街。 傳聞我的和親對象是個殘疾皇子风题,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容