CountDownLatch和CyclicBarrier的區(qū)別
(1) CountDownLatch的作用是允許1或N個(gè)線程等待其他線程完成執(zhí)行滞时;而CyclicBarrier則是允許N個(gè)線程相互等待。
(2) CountDownLatch的計(jì)數(shù)器無(wú)法被重置滤灯;CyclicBarrier的計(jì)數(shù)器可以被重置后使用坪稽,因此它被稱為是循環(huán)的barrier。
(3) CountDownLatch 參與的線程的職責(zé)是不一樣的鳞骤,有的在倒計(jì)時(shí)窒百,有的在等待倒計(jì)時(shí)結(jié)束。CyclicBarrier 參與的線程職責(zé)是一樣的豫尽。
(4)?CyclicBarrier 還可以設(shè)置回調(diào)函數(shù)篙梢,?回調(diào)函數(shù)執(zhí)行在一個(gè)回合里最后執(zhí)行await()的線程上,?為同步調(diào)用回調(diào)函數(shù)拂募。一般會(huì)開(kāi)啟一個(gè)線程池異步處理回調(diào)函數(shù)庭猩。
一窟她、countDownLatch
1陈症、使用場(chǎng)景:
1: 某一線程在開(kāi)始運(yùn)行前等待n個(gè)線程執(zhí)行完畢。
將CountDownLatch的計(jì)數(shù)器初始化為n:new CountDownLatch(n) 震糖,每當(dāng)一個(gè)任務(wù)線程執(zhí)行完畢录肯,就將計(jì)數(shù)器減1, countdownlatch.countDown()吊说,當(dāng)計(jì)數(shù)器的值變?yōu)?時(shí)论咏,在CountDownLatch上 await() 的線程就會(huì)被喚醒。一個(gè)典型應(yīng)用場(chǎng)景就是啟動(dòng)一個(gè)服務(wù)時(shí)颁井,主線程需要等待多個(gè)組件加載完畢厅贪,之后再繼續(xù)執(zhí)行。
一種典型的場(chǎng)景就是火箭發(fā)射雅宾。在火箭發(fā)射前养涮,為了保證萬(wàn)無(wú)一失,往往還要進(jìn)行各項(xiàng)設(shè)備眉抬、儀器的檢查贯吓。 只有等所有檢查完畢后,引擎才能點(diǎn)火蜀变。
2:實(shí)現(xiàn)多個(gè)線程開(kāi)始執(zhí)行任務(wù)的最大并行性悄谐。
注意是并行性,不是并發(fā)库北,強(qiáng)調(diào)的是多個(gè)線程在某一時(shí)刻同時(shí)開(kāi)始執(zhí)行爬舰。做法是初始化一個(gè)共享的CountDownLatch(1)们陆,將其計(jì)數(shù)器初始化為1,多個(gè)線程在開(kāi)始執(zhí)行任務(wù)前首先 coundownlatch.await()洼专,當(dāng)主線程調(diào)用 countDown() 時(shí)棒掠,計(jì)數(shù)器變?yōu)?,多個(gè)線程同時(shí)被喚醒屁商。
2烟很、簡(jiǎn)單介紹:
1、同步的輔助類蜡镶,允許一個(gè)或多個(gè)線程雾袱,等待其他一組線程完成操作,再繼續(xù)執(zhí)行官还。
2芹橡、CountDownLatch是通過(guò)“共享鎖”實(shí)現(xiàn)的。在創(chuàng)建CountDownLatch中時(shí)望伦,會(huì)傳遞一個(gè)int類型參數(shù)count林说,該參數(shù)是“鎖計(jì)數(shù)器”的初始狀態(tài),表示該“共享鎖”最多能被count給線程同時(shí)獲取屯伞。當(dāng)某線程調(diào)用該CountDownLatch對(duì)象的await()方法時(shí)腿箩,該線程會(huì)等待“共享鎖”可用時(shí),才能獲取“共享鎖”進(jìn)而繼續(xù)運(yùn)行劣摇。而“共享鎖”可用的條件珠移,就是“鎖計(jì)數(shù)器”的值為0!而“鎖計(jì)數(shù)器”的初始值為count末融,每當(dāng)一個(gè)線程調(diào)用該CountDownLatch對(duì)象的countDown()方法時(shí)钧惧,才將“鎖計(jì)數(shù)器”-1;通過(guò)這種方式勾习,必須有count個(gè)線程調(diào)用countDown()之后浓瞪,“鎖計(jì)數(shù)器”才為0,而前面提到的等待線程才能繼續(xù)運(yùn)行巧婶!
3乾颁、實(shí)現(xiàn)原理:
?1)通過(guò)“共享鎖”實(shí)現(xiàn)。CountDownLatch是通過(guò)一個(gè)計(jì)數(shù)器來(lái)實(shí)現(xiàn)的粹舵,計(jì)數(shù)器的初始值為需要等待線程的數(shù)量钮孵。
eg:CountDownLatch c = new CountDownLatch(10); // 等待線程的數(shù)量為10
?2)主線程調(diào)用CountDownLatch的await()方法會(huì)阻塞當(dāng)前線程(即:主線程在閉鎖上等待),直到計(jì)數(shù)器的值為0眼滤。
?3)當(dāng)一個(gè)工作線程完成了自己的任務(wù)后巴席,調(diào)用CountDownLatch的countDown()方法,計(jì)數(shù)器的值就會(huì)減1诅需。
?4)當(dāng)計(jì)數(shù)器值為0時(shí)漾唉,說(shuō)明所有的工作線程都執(zhí)行完了荧库,此時(shí),在閉鎖上等待的主線程就可以恢復(fù)執(zhí)行任務(wù)赵刑。
4分衫、例子:
public class CountDownLatchTest1 {
? ? private static CountDownLatch doneSignal=new CountDownLatch(5);
? ? public static void main(String[] args) {
? ? ? ? try {
? ? ? ? ? for(int i=0; i<5; i++){
? ? ? ? ? ? ? ? new InnerThread().start();
? ? ? ? ? ? ????System.out.println("main await begin.");
? ? ? ? ? ? ????doneSignal.await();// "主線程"等待線程池中5個(gè)任務(wù)的完成
? ? ? ? ? ? ????System.out.println("main await finished.");
? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? static class InnerThread extends Thread{
? ? ? ? public void run() {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? Thread.sleep(1000);
? ? ? ? ? ? ? ? System.out.println(Thread.currentThread().getName() + " sleep 1000ms.");
? ? ? ? ? ? ? ? doneSignal.countDown();?// 將CountDownLatch的數(shù)值減1
? ? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
main await begin.
Thread-0 sleep 1000ms.
Thread-2 sleep 1000ms.
Thread-1 sleep 1000ms.
Thread-4 sleep 1000ms.
Thread-3 sleep 1000ms.
main await finished.
結(jié)果說(shuō)明:主線程通過(guò)doneSignal.await()等待其它線程將doneSignal遞減至0。其它的5個(gè)InnerThread線程般此,每一個(gè)都通過(guò)doneSignal.countDown()將doneSignal的值減1蚪战;當(dāng)doneSignal為0時(shí),main被喚醒后繼續(xù)執(zhí)行铐懊。
5邀桑、源碼分析:
稍后附加
https://www.cnblogs.com/skywang12345/p/3533887.html
二、CyclicBarrier
1科乎、使用場(chǎng)景:
1)生活中我們會(huì)約朋友們到某個(gè)餐廳一起吃飯壁畸,有些朋友可能會(huì)早到,有些朋友可能會(huì)晚到茅茂,但是這個(gè)餐廳規(guī)定必須等到所有人到齊之后才會(huì)讓我們進(jìn)去捏萍。這里的朋友們就是各個(gè)線程,餐廳就是 CyclicBarrier空闲。
2)一個(gè)線程組的線程需要等待所有線程完成任務(wù)后再繼續(xù)執(zhí)行下一次任務(wù)令杈。可以用于多線程計(jì)算數(shù)據(jù)进副,最后合并計(jì)算結(jié)果的場(chǎng)景这揣。
例子:模擬多線程分組計(jì)算
有一個(gè)大小為50000的隨機(jī)數(shù)組悔常,用5個(gè)線程分別計(jì)算10000個(gè)元素的和影斑,然后在將計(jì)算結(jié)果進(jìn)行合并,得出最后的結(jié)果机打。各種應(yīng)用例子
比如現(xiàn)在需要計(jì)算10個(gè)人12個(gè)月內(nèi)的工資詳細(xì)矫户,可以將線程分為10個(gè),分別計(jì)算每個(gè)人的工資残邀,最后皆辽,再用barrierAction將這些線程的計(jì)算結(jié)果進(jìn)行整合,得出最后結(jié)果芥挣。
3)舉個(gè)報(bào)旅行團(tuán)旅行的例子驱闷。
出發(fā)時(shí),導(dǎo)游會(huì)在機(jī)場(chǎng)收了護(hù)照和簽證空免,辦理集體出境手續(xù)空另,所以,要等大家都到齊才能出發(fā)蹋砚,出發(fā)前再把護(hù)照和簽證發(fā)到大家手里扼菠。
對(duì)應(yīng)CyclicBarrier使用摄杂。每個(gè)人到達(dá)后進(jìn)入barrier狀態(tài)。都到達(dá)后循榆,喚起大家一起出發(fā)去旅行析恢。旅行出發(fā)前,導(dǎo)游還會(huì)有個(gè)發(fā)護(hù)照和簽證的動(dòng)作秧饮。 ??http://www.reibang.com/p/4ef4bbf01811
2映挂、簡(jiǎn)單介紹:
CyclicBarrier的字面意思是可循環(huán)使用(Cyclic)的屏障(Barrier)。它要做的事情是盗尸,讓一組線程到達(dá)一個(gè)屏障(也可以叫同步點(diǎn))時(shí)被阻塞袖肥,直到最后一個(gè)線程到達(dá)屏障時(shí),屏障才會(huì)開(kāi)門(mén)振劳,所有被屏障攔截的線程才會(huì)繼續(xù)運(yùn)行椎组。和CountDownLatch相似,也是等待某些線程都做完以后再執(zhí)行历恐。
3寸癌、實(shí)現(xiàn)原理:
1、CyclicBarrier是通過(guò)一個(gè)計(jì)數(shù)器來(lái)實(shí)現(xiàn)的弱贼,計(jì)數(shù)器的初始值為需要等待線程的數(shù)量蒸苇。
eg:CyclicBarrier c = new CyclicBarrier(2); // 等待線程的數(shù)量為2
2)每個(gè)線程調(diào)用CyclicBarrier的await()方法,使自己進(jìn)入等待狀態(tài)吮旅。
3)當(dāng)所有的線程都調(diào)用了CyclicBarrier的await()方法后溪烤,所有的線程停止等待,繼續(xù)運(yùn)行庇勃。
4檬嘀、例子:
從打印結(jié)果可以看出,所有線程會(huì)等待全部線程到達(dá)柵欄之后才會(huì)繼續(xù)執(zhí)行责嚷,并且最后到達(dá)的線程會(huì)完成 Runnable 的任務(wù)鸳兽。
5、源碼分析:
https://www.cnblogs.com/skywang12345/p/3533995.html
稍后附加