XML DOM 獲取節(jié)點(diǎn)值
730
2025-03-31
原文:Java CyclicBarrier與CountDownLatch
1.簡(jiǎn)介
在本教程中,我們將比較?CyclicBarrier?和?CountDownLatch并嘗試了解兩者之間的異同。
2.這些是什么?
當(dāng)涉及到并發(fā)時(shí),將每個(gè)對(duì)象要完成的概念概念化可能是一個(gè)挑戰(zhàn)。
首先,CountDownLatch和CyclicBarrier都用于管理多線程應(yīng)用程序。
而且,它們都旨在表示給定線程或線程組應(yīng)如何等待。
2.1。?CountDownLatch(自減門閂)
一個(gè)?CountDownLatch?是一個(gè)結(jié)構(gòu),一個(gè)線程等待其他線程?倒計(jì)時(shí)門閂直至為零。
我們可以將其想象為正在準(zhǔn)備的餐廳的一道菜。無論由哪個(gè)廚師準(zhǔn)備?n種?食物,服務(wù)員都必須等到所有食物都放在盤子上。如果一個(gè)盤子可?容納n個(gè)?物品,那么任何廚師都會(huì)?在他放在盤子上的一個(gè)物品的同時(shí)對(duì)倒計(jì)時(shí)門閂減一操作。
2.2。?CyclicBarrier(循環(huán)阻障)
甲?的CyclicBarrier?是可重復(fù)使用的構(gòu)建體,其中一組線程等待在一起,直到所有線程?到達(dá)。在這一點(diǎn)上,所述屏障破裂,一個(gè)?動(dòng)作可任選地服用。
我們可以將其視為一群朋友。每當(dāng)他們計(jì)劃在餐廳用餐時(shí),他們都會(huì)決定可以見面的共同點(diǎn)。他們?cè)谀莾旱戎?,只有每個(gè)人到了,他們才能一起去餐廳吃飯。
2.3。進(jìn)一步閱讀
有關(guān)每個(gè)單獨(dú)組件的更多詳細(xì)信息,請(qǐng)分別參考我們之前關(guān)于CountDownLatch?和CyclicBarrier的教程??。
3.任務(wù)與線程
讓我們更深入地研究這兩個(gè)類之間的一些語義差異。
如定義中所述,CyclicBarrier允許多個(gè)線程互相等待,而CountDownLatch允許一個(gè)或多個(gè)線程等待許多任務(wù)完成。
簡(jiǎn)而言之,CyclicBarrier維護(hù)線程數(shù),而CountDownLatch維護(hù)任務(wù)數(shù)。
在下面的代碼中,我們定義了一個(gè)計(jì)數(shù)為2的CountDownLatch。接下來,我們從單個(gè)線程兩次調(diào)用?countDown():
CountDownLatch?countDownLatch?=?new?CountDownLatch(2); Thread?t?=?new?Thread(()?->?{ ????countDownLatch.countDown(); ????countDownLatch.countDown(); }); t.start(); countDownLatch.await(); assertEquals(0,?countDownLatch.getCount());
一旦鎖存器達(dá)到零,等待?調(diào)用就會(huì)返回。
請(qǐng)注意,在這種情況下,我們能夠使同一線程將計(jì)數(shù)減少兩次。
但是,CyclicBarrier在這一點(diǎn)上有所不同。
與上面的示例類似,我們創(chuàng)建一個(gè)CyclicBarrier,它的計(jì)數(shù)再次為2,并在同一線程上調(diào)用await()兩次:
CyclicBarrier?cyclicBarrier?=?new?CyclicBarrier(2); Thread?t?=?new?Thread(()?->?{ ????try?{ ????????cyclicBarrier.await(); ????????cyclicBarrier.await();???? ????}?catch?(InterruptedException?|?BrokenBarrierException?e)?{ ????????//?error?handling ????} }); t.start(); assertEquals(1,?cyclicBarrier.getNumberWaiting()); assertFalse(cyclicBarrier.isBroken());
這里的第一個(gè)區(qū)別是正在等待的線程就是barrier(障礙)本身。
其次,更重要的是,第二個(gè)await()?是無用的。單個(gè)線程無法對(duì)Barrier(障礙)做兩次自減。
確實(shí),因?yàn)?t必須?等待另一個(gè)線程調(diào)用?await()?才能使計(jì)數(shù)增加到2,所以t的第二次對(duì)await()的?調(diào)用實(shí)際上不會(huì)被調(diào)用,直到屏障已經(jīng)被打破!
在我們的測(cè)試中,沒有越過障礙,因?yàn)槲覀冎挥幸粋€(gè)線程在等待,而沒有兩個(gè)線程將使障礙被觸發(fā)。從CyclicBarrier.isBroken()方法也很明顯,該方法返回false。
4.可重用性
這兩個(gè)類別之間第二個(gè)最明顯的區(qū)別是可重用性。詳細(xì)地說,當(dāng)屏障在CyclicBarrier中跳閘時(shí)?,計(jì)數(shù)將重置為其原始值。?CountDownLatch是不同的,因?yàn)橛?jì)數(shù)永遠(yuǎn)不會(huì)重置。
在給定的代碼中,我們定義了一個(gè)CountCount為7的CountDownLatch,并通過20個(gè)不同的調(diào)用對(duì)其進(jìn)行計(jì)數(shù):
CountDownLatch?countDownLatch?=?new?CountDownLatch(7); ExecutorService?es?=?Executors.newFixedThreadPool(20); for?(int?i?=?0;?i?20;?i++)?{ ????es.execute(()?->?{ ????????long?prevValue?=?countDownLatch.getCount(); ????????countDownLatch.countDown(); ????????if?(countDownLatch.getCount()?!=?prevValue)?{ ????????????outputScraper.add("Count?Updated"); ????????} ????});? }? es.shutdown(); assertTrue(outputScraper.size()?<=?7);
我們觀察到,即使有20個(gè)不同的線程調(diào)用?countDown(),計(jì)數(shù)一旦達(dá)到零也不會(huì)重置。
與上面的示例類似,我們定義一個(gè)Countic?7的CyclicBarrier?并從20個(gè)不同的線程中等待它:
CyclicBarrier?cyclicBarrier?=?new?CyclicBarrier(7); ExecutorService?es?=?Executors.newFixedThreadPool(20); for?(int?i?=?0;?i?20;?i++)?{ ????es.execute(()?->?{ ????????try?{ ????????????if?(cyclicBarrier.getNumberWaiting()?<=?0)?{ ????????????????outputScraper.add("Count?Updated"); ????????????} ????????????cyclicBarrier.await(); ????????}?catch?(InterruptedException?|?BrokenBarrierException?e)?{ ????????????//?error?handling ????????} ????}); } es.shutdown(); assertTrue(outputScraper.size()?>?7);
在這種情況下,我們觀察到每次運(yùn)行新線程時(shí)該值都會(huì)減小,一旦達(dá)到零,就會(huì)重置為原始值。
5.結(jié)論
總而言之,??CyclicBarrier和CountDownLatch?都是在多個(gè)線程之間進(jìn)行同步的有用工具。但是,它們?cè)诠δ苌细静煌?。在確定最適合該工作時(shí),請(qǐng)仔細(xì)考慮每個(gè)因素。
像往常一樣,所有討論的示例都可以在Github上訪問。
其他相關(guān)討論:
Java concurrency: Countdown latch vs Cyclic barrier
CountDownLatch與CyclicBarrier
Java
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。