Java并發(fā)之CountDownLatch(等待多個并發(fā)事件的完成)

  • 引入CountDownLatch類
  • CountDownLatch類的具體實例
  • CountDownLatch小結(jié)

引入CountDownLatch類

Java在JDK1.5之后引入了CountDownLatch類郑气。這個類是一個同步輔助類栗竖。用于一個線程等待多個操作完成之后再執(zhí)行,也就是這個當(dāng)前線程會一直阻塞回懦,直到它所等待的多個操作已經(jīng)完成态贤。首先CountDownLatch類會初始化舱呻,設(shè)置它需要等待完成的操作的數(shù)量。然后每當(dāng)一個操作完成之后悠汽,就會調(diào)用countDown方法箱吕,這個方法會將CountDownLatch內(nèi)部的計數(shù)器減一。當(dāng)減為0的時候柿冲,CountDownLatch類會喚醒所有調(diào)用await方法而進(jìn)入休眠的線程茬高。

CountDownLatch類的具體實例

多說無意,我們具體看一個實例就可以理解CountDownLatch類的使用了假抄。

我們舉一個最直觀的例子怎栽,比如我們需要開一個視頻會議,這個會議需要等待一定的人數(shù)到達(dá)之后慨亲,才開始會議婚瓜。這種情況就非常適合使用CountDownLatch類來進(jìn)行同步,也就是等待多個并發(fā)事件的發(fā)生刑棵,因為每個參會人員的到達(dá)是并發(fā)的巴刻。

首先我們實現(xiàn)會議類,這個類持有一個CountDownLatch類的對象蛉签,并且定義了一個arrive方法胡陪,每當(dāng)會議人員到達(dá)之后沥寥,就會調(diào)用這個方法,告訴會議已經(jīng)到達(dá)了柠座,這個方法邑雅,會調(diào)用CountDown方法,將計數(shù)器減一妈经。

在會議類的run方法中淮野,在宣布會議開始之前,會調(diào)用CountDownLatch類的await方法休眠吹泡,直到countDown減為0骤星,也就是計數(shù)器減為0,說明所有的人都到了爆哑,才喚醒繼續(xù)這個線程的代碼洞难,宣布會議開始

package CountDown;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class VideoConference implements Runnable  {
    
    private final CountDownLatch controller;
    
    public VideoConference(int number) {
        controller = new CountDownLatch(10);
    }
    
    public synchronized void arrive(String name) {
        
        
        System.out.println(name + " has arrived.");
        
        System.out.println("VideoConference : waiting for " + (controller.getCount() - 1) + " partivipants");
        
        
        controller.countDown();
    }
    
    @Override
    public void run() {
        System.out.println("VideoConference : Innitiaization : " + controller.getCount() + " participants");
        
        try {
            controller.await();
            System.out.println("All people has come");
            System.out.println("Let's start...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

接著我們實現(xiàn)參會人員的類,這個類也實現(xiàn)了runnable接口揭朝,首先它持有一個會議對象队贱,為了在執(zhí)行的時候調(diào)用arrive方法,告訴會議人員到了潭袱。

package CountDown;

import java.util.concurrent.TimeUnit;

public class Participant implements Runnable {

    private VideoConference conference;
    
    private String name;
    
    public Participant(VideoConference conference, String name) {
        this.conference = conference;
        this.name = name;
    }
    
    
    @Override
    public void run() {
        long duration = (long)Math.random() * 10;
        
        try {
            TimeUnit.SECONDS.sleep(duration + 10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        conference.arrive(name);
    }

}

最后我們實現(xiàn)測試類

package CountDown;

public class Main {

    public static void main(String[] args) {
        
        VideoConference conference = new VideoConference(10);
        
        new Thread(conference).start();
        
        for(int i=0;i<10;i++) {
            Participant p = new Participant(conference, "Participant " + i);
            new Thread(p).start();
        }
    }
}

運行結(jié)果:

image.png

await方法還可以指定休眠的時間柱嫌,當(dāng)休眠時間到了或者計數(shù)器減為0,就會喚醒所有被CountDownLatch休眠的線程敌卓,那我們在這里就可以使用這個休眠時間來設(shè)置慎式,我們只等10s中伶氢,如果10s中趟径,還有人沒到,我們也不管了癣防,先開始會議蜗巧。

只需對run方法進(jìn)行簡單的修改:

@Override
    public void run() {
        System.out.println("VideoConference : Innitiaization : " + controller.getCount() + " participants");
        
        try {
            controller.await(10, TimeUnit.SECONDS);
            if(controller.getCount() == 0) {
                System.out.println("All people has come");
                System.out.println("Let's start...");
            }
            else {
                System.out.println("不等了");
                System.out.println("Let's start...");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

運行結(jié)果

image.png

CountDownLatch小結(jié)

CountDownLatch有三個基本的要素:

  • 一個初始值,定義必須等待多少個并發(fā)線程完成的數(shù)目

  • await方法蕾盯,需要等到其他操作先完成的那個線程調(diào)用的幕屹,先將線程休眠,直到其他操作完成级遭,計數(shù)器減為0望拖,才會喚醒因此休眠的線程

  • countDown方法,每個被等待的事件在完成之后調(diào)用挫鸽,會將計數(shù)器減一

  • CountDownLatch不是用來保護(hù)臨界區(qū)和共享資源的说敏,是用來同步執(zhí)行線程和操作的

  • CountDownLatch是一次性的,當(dāng)計數(shù)器減為0 之后丢郊,這個類就相當(dāng)于沒用盔沫,我們之后對它的操作都不起作用医咨,需要新建一個countDownLatch類

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市架诞,隨后出現(xiàn)的幾起案子拟淮,更是在濱河造成了極大的恐慌,老刑警劉巖谴忧,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件很泊,死亡現(xiàn)場離奇詭異,居然都是意外死亡沾谓,警方通過查閱死者的電腦和手機撑蚌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搏屑,“玉大人争涌,你說我怎么就攤上這事±绷担” “怎么了亮垫?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長伟骨。 經(jīng)常有香客問我饮潦,道長,這世上最難降的妖魔是什么携狭? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任继蜡,我火速辦了婚禮,結(jié)果婚禮上逛腿,老公的妹妹穿的比我還像新娘稀并。我一直安慰自己,他們只是感情好单默,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布碘举。 她就那樣靜靜地躺著,像睡著了一般搁廓。 火紅的嫁衣襯著肌膚如雪引颈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天境蜕,我揣著相機與錄音蝙场,去河邊找鬼。 笑死粱年,一個胖子當(dāng)著我的面吹牛售滤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播逼泣,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼趴泌,長吁一口氣:“原來是場噩夢啊……” “哼舟舒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嗜憔,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤秃励,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后吉捶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夺鲜,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年呐舔,在試婚紗的時候發(fā)現(xiàn)自己被綠了币励。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡珊拼,死狀恐怖食呻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情澎现,我是刑警寧澤仅胞,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站剑辫,受9級特大地震影響干旧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜妹蔽,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一椎眯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胳岂,春花似錦编整、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至成艘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贺归,已是汗流浹背淆两。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拂酣,地道東北人秋冰。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像婶熬,于是被迫代替她去往敵國和親剑勾。 傳聞我的和親對象是個殘疾皇子埃撵,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

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