并發(fā)面試題:CountDownLatch、CyclicBarrie慰毅、Semaphorer三者的區(qū)別

23. CountDownLatch****類

CountDownLatch類似計(jì)數(shù)器的功能隘截,CountDownLatch是一種靈活的閉鎖實(shí)現(xiàn),能夠使一個(gè)線程在等待另外一些線程完成各自工作之后汹胃,再繼續(xù)執(zhí)行婶芭。使用一個(gè)計(jì)數(shù)器進(jìn)行實(shí)現(xiàn)。計(jì)數(shù)器初始值為線程的數(shù)量着饥。當(dāng)每一個(gè)線程完成自己任務(wù)后犀农,計(jì)數(shù)器的值就會(huì)減一。當(dāng)計(jì)數(shù)器的值為0時(shí)宰掉,表示所有的線程都已經(jīng)完成了任務(wù)井赌,然后在CountDownLatch上等待的線程就可以恢復(fù)執(zhí)行任務(wù)。

需求1:計(jì)算10個(gè)學(xué)生搶蘋果的總時(shí)間贵扰。

問題代碼:

public class NoCountDownLatchDemo {

public static voidmain(String[] args) throws InterruptedException {

long begin = System.currentTimeMillis();

Apple apple= new Apple();

for (int i= 0; i< 10; i++) {

new Thread(apple).start();

}

long end = System.currentTimeMillis();

System.out.println("共耗費(fèi)" + (end- begin) + "ms時(shí)間");

}

}

classApple implements Runnable {

private int appleNum = 100;

@Override

public void run() {

for (int i= 0; i< 1000; i++) {

synchronized (this) {

if (appleNum > 0) {

System.out.println(Thread.currentThread().getName() + "搶到第"+ appleNum-- + "個(gè)蘋果");

}

}

}

}

}

測(cè)試結(jié)果:

[圖片上傳失敗...(image-c7bb34-1548232986922)]

問題分析:

耗費(fèi)總時(shí)間應(yīng)該是蘋果搶完之后才計(jì)算出來的仇穗,現(xiàn)在還在搶的過程中就計(jì)算出來了,所以我們需要在計(jì)算消耗時(shí)間之前設(shè)置一個(gè)關(guān)卡戚绕,判斷搶蘋果線程是否都結(jié)束纹坐,如果都結(jié)束了就執(zhí)行時(shí)間的計(jì)算。

分析如圖所示:

[圖片上傳失敗...(image-332aef-1548232986922)]

正確代碼:

public class CountDownLatchDemo {

public static voidmain(String[] args) throws InterruptedException {

CountDownLatch latch= new CountDownLatch(10);

long begin = System.currentTimeMillis();

Apple1 apple= new Apple1(latch);

for (int i= 0; i< 10; i++) {

new Thread(apple).start();

}

latch.await();//不讓main線程往下運(yùn)行舞丛,直到吃蘋果線程都運(yùn)行完畢耘子,才放行

long end = System.currentTimeMillis();

System.out.println("共耗費(fèi)"+(end-begin)+"ms時(shí)間");

}

}

classApple1 implements Runnable{

private int appleNum = 100;

privateCountDownLatch latch;

publicApple1(CountDownLatch latch) {

this.latch= latch;

}

@Override

public void run() {

try {

for (int i= 0; i< 1000; i++) {

synchronized (this) {

if (appleNum>0) {

System.out.println(Thread.currentThread().getName()+"搶到第"+appleNum--+"個(gè)蘋果");

}

}

}

} finally {//必須要執(zhí)行

latch.countDown();

}

}

}

24. CyclicBarrier****類

CyclicBarrier回環(huán)柵欄果漾,通過它可以實(shí)現(xiàn)讓一組線程等待至某個(gè)狀態(tài)之后再全部同時(shí)執(zhí)行。叫做回環(huán)是因?yàn)楫?dāng)所有等待線程都被釋放以后谷誓,CyclicBarrier可以被重用绒障。我們暫且把這個(gè)狀態(tài)就叫做barrier,當(dāng)調(diào)用await()方法之后捍歪,線程就處于barrier了户辱。

需求:通知10個(gè)線程開會(huì),線程到達(dá)會(huì)議室的時(shí)間是不一致的糙臼,人齊開會(huì)庐镐。

代碼演示:

public class CyclicBarrierDemo {

public static voidmain(String[] args) {

CyclicBarrier barrier= newCyclicBarrier(10, new Runnable() {

@Override

public void run() {

System.out.println("人已經(jīng)到齊,準(zhǔn)備開會(huì)变逃!");

}

});

for (int i= 0; i< 10; i++) {

new Thread(new Meet(barrier)).start();

}

}

}

classMeet implements Runnable {

privateCyclicBarrier barrier;

publicMeet(CyclicBarrier barrier) {

this.barrier= barrier;

}

public void meeting() {

System.out.println(Thread.currentThread().getName() + "到達(dá)會(huì)議室等待");

try {

barrier.await();//中間設(shè)置了一道屏障

} catch(Exception e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName() + "開會(huì)中必逆!");

}

@Override

public void run() {

meeting();

}

}

25. Semaphore****類

Semaphore英文含義為信號(hào)量,Semaphore可以控制同時(shí)訪問的線程個(gè)數(shù)揽乱,通過 acquire() 獲取一個(gè)許可名眉,如果沒有就等待,而 release() 釋放一個(gè)許可凰棉。

需求:模擬車子等紅路燈璧针,綠燈表示線程獲取許可哦,通過馬路渊啰,但是是一批一批的過馬路探橱,過馬路的車輛數(shù)量是固定的,最多不能超過這個(gè)數(shù)绘证。

代碼演示:

public class SemaphoreDemo {

public static voidmain(String[] args) {

Semaphore semaphore= new Semaphore(10);

for (int i= 0; i< 100; i++) {

new Thread(new Car(semaphore)).start();

}

}

}

classCar implements Runnable{

privateSemaphore semaphore;

publicCar(Semaphore semaphore) {

super();

this.semaphore= semaphore;

}

@Override

public void run() {

try {

semaphore.acquire();//綠燈,獲得許可證

Thread.sleep(5000);

System.out.println(Thread.currentThread().getName()+"-->"+"一批一批過馬路");

semaphore.release();//許可證發(fā)完隧膏,轉(zhuǎn)紅燈

} catch(InterruptedException e) {

e.printStackTrace();

}

}

}

26. CountDownLatch****、****CyclicBarrie****嚷那、****Semaphorer****三者的區(qū)別

? CountDownLatch:使一個(gè)線程A或是組線程A等待其它線程執(zhí)行完畢后胞枕,一個(gè)線程A或是組線程A才繼續(xù)執(zhí)行(發(fā)現(xiàn)參差不齊,等一等魏宽,重新在起步)腐泻。CyclicBarrier:等所有的線程到達(dá)一個(gè)點(diǎn),中間做完barrierAction的事情之后队询,才能重新各自做各自的事情派桩。(人齊來會(huì),開會(huì)后蚌斩,各自完成各自任務(wù))Semaphore:一批一批線程執(zhí)行

? CountDownLatch是減計(jì)數(shù)方式铆惑,計(jì)數(shù)==0時(shí)釋放所有等待的線程;CyclicBarrier是加計(jì)數(shù)方式,計(jì)數(shù)達(dá)到指定的值時(shí)釋放所有等待的線程员魏。Semaphore調(diào)用semaphore.acquire()得到一個(gè)許可丑蛤,當(dāng)許可到了一定的數(shù)量時(shí)可以開始執(zhí)行線程.

? CountDownLatch當(dāng)計(jì)數(shù)到0時(shí),計(jì)數(shù)無法被重置撕阎;CyclicBarrier計(jì)數(shù)達(dá)到指定值時(shí)受裹,此時(shí)計(jì)數(shù)設(shè)置為0,又可以重新開始虏束。

? CountDownLatch每次調(diào)用countDown()方法計(jì)數(shù)減一棉饶,調(diào)用await()方法只進(jìn)行阻塞,對(duì)計(jì)數(shù)沒任何影響魄眉;CyclicBarrier只有一個(gè)await()方法,調(diào)用await()方法計(jì)數(shù)加1闷袒,若加1后的值不等于構(gòu)造方法的值坑律,則線程阻塞。

? CountDownLatch囊骤、CyclikBarrier這個(gè)值作為計(jì)數(shù)用晃择,達(dá)到該次數(shù)即釋放等待的線程,而Semaphore 中所有acquire獲取到的資源達(dá)到這個(gè)數(shù)也物,會(huì)使得其它線程阻塞宫屠。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市滑蚯,隨后出現(xiàn)的幾起案子浪蹂,更是在濱河造成了極大的恐慌,老刑警劉巖告材,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坤次,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡斥赋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冰垄,“玉大人阳似,你說我怎么就攤上這事“欤” “怎么了疑故?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)弯菊。 經(jīng)常有香客問我焰扳,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任吨悍,我火速辦了婚禮扫茅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘育瓜。我一直安慰自己葫隙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布躏仇。 她就那樣靜靜地躺著恋脚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪焰手。 梳的紋絲不亂的頭發(fā)上糟描,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音书妻,去河邊找鬼船响。 笑死,一個(gè)胖子當(dāng)著我的面吹牛躲履,可吹牛的內(nèi)容都是我干的见间。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼工猜,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼米诉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起篷帅,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤史侣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后魏身,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抵窒,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年叠骑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了李皇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宙枷,死狀恐怖掉房,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情慰丛,我是刑警寧澤卓囚,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站诅病,受9級(jí)特大地震影響哪亿,放射性物質(zhì)發(fā)生泄漏粥烁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一蝇棉、第九天 我趴在偏房一處隱蔽的房頂上張望讨阻。 院中可真熱鬧,春花似錦篡殷、人聲如沸钝吮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奇瘦。三九已至,卻和暖如春劲弦,著一層夾襖步出監(jiān)牢的瞬間耳标,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工邑跪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留次坡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓呀袱,卻偏偏與公主長(zhǎng)得像贸毕,于是被迫代替她去往敵國(guó)和親郑叠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子夜赵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

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