您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Java多線程同步工具類CountDownLatch怎么使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“Java多線程同步工具類CountDownLatch怎么使用”吧!
CountDownLatch
是一個多線程同步工具類,在多線程環(huán)境中它允許多個線程處于等待狀態(tài),直到前面的線程執(zhí)行結(jié)束。從類名上看CountDown
既是數(shù)量遞減的意思,我們可以把它理解為計數(shù)器。
countDown()
:計數(shù)器遞減方法。
await()
:使調(diào)用此方法的線程進(jìn)入等待狀態(tài),直到計數(shù)器計數(shù)為0時主線程才會被喚醒。
await(long, TimeUnit)
:在await()
方法的基礎(chǔ)上增加了超時策略,若等待超時仍未有結(jié)果則會直接喚醒主線程運行。
在這里我們用一段簡單的代碼進(jìn)行演示:
@Slf4j public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(3); new Thread(() -> { log.info("hello this is thread one"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } countDownLatch.countDown(); }).start(); new Thread(() -> { log.info("hello this is thread two"); countDownLatch.countDown(); }).start(); new Thread(() -> { log.info("hello this is thread three"); countDownLatch.countDown(); }).start(); countDownLatch.await(); log.info("say good bye!"); } }
由上面的代碼可見,我們創(chuàng)建了一個CountDownLatch
計數(shù)器為3和三個線程同步運行。在main主線程中調(diào)用了countDownLatch.await()
方法使主線程進(jìn)入阻塞。其中三個線程任務(wù)執(zhí)行完畢后都會調(diào)用countDownLatch.countDown()
方法對計數(shù)器進(jìn)行遞減,當(dāng)三個線程任務(wù)都執(zhí)行完畢后計數(shù)器計數(shù)值為0時主線程被喚醒。
注:在創(chuàng)建
CountDownLatch
實例時必須定義計數(shù)器值,一般相對較合理的用法是該值的定義需要經(jīng)過合理的計算使計數(shù)值與需要并行的線程數(shù)相等,在每個線程執(zhí)行完成后做計數(shù)遞減,最終喚醒主線程繼續(xù)執(zhí)行。
CountDownLatch
計數(shù)值設(shè)置大于線程數(shù),那么最終所有線程都執(zhí)行完了,而計數(shù)為遞減到0那么主線程將會一直處于等待狀態(tài)。
CountDownLatch
計數(shù)值設(shè)置小于并發(fā)線程數(shù),那么可能在部分線程未執(zhí)行完畢時,計數(shù)就已經(jīng)遞減到0,則主線程會被提前喚醒。
如下圖,主線程阻塞與喚醒的核心就是計數(shù)器,只有當(dāng)所有線程執(zhí)行完成計數(shù)逐個遞減最終才會喚起await()
阻塞中的主線程。
注:
await()
可以阻塞一個線程,也可以阻塞多個線程,如果是阻塞多個線程,那么在計數(shù)為0時將會喚醒所有被阻塞的線程。
在簡單了解完CountDownLatch
的作用后,相信各位最終目的還是想了解如何去使用,在哪些場景下使用更加合適,接下來我就拿一個對賬業(yè)務(wù)的場景詳細(xì)分析一下。
相信現(xiàn)在很多平臺都會對接銀聯(lián)、微信、支付寶等支付渠道做交易,那么在這樣的場景下對賬是不可避免的。對賬通常都會在每日的凌晨去處理,一方面是凌晨時間點多數(shù)平臺訪問量都會較小,服務(wù)器壓力也比較輕松,而且此時出賬也比較合理,所以在這個時間點做對賬也是一個大數(shù)據(jù)量計算的操作。
上面講這么多好像都沒說到重點,在處理對賬之前首先我們肯定是需要通過各個支付渠道獲取對賬單文件,那么該如何操作呢?
對賬文件下載(第一階段):在這種情況下可以設(shè)計三個任務(wù)并發(fā)去獲取對賬文件,使用CountDownLatch
阻塞主線程,等待三個任務(wù)都獲取到文件的時候做計數(shù)遞減,最終喚醒主線將標(biāo)記本階段處理完成,并發(fā)起進(jìn)入下一階段的通知。
對賬文件解析(第二階段):在上個階段已下載完成的文件文件中,此階段要做的就是解析文件。由于三個渠道都是不同的廠家那么文件的內(nèi)容格式肯定都是不一樣的,這時候我們又可以使用CountDownLatch
啟動三個線程分別去解析各自的對賬文件,最終將文件內(nèi)容轉(zhuǎn)換為業(yè)務(wù)所需的數(shù)據(jù)統(tǒng)一格式入庫,在三個任務(wù)都入庫完成后主線程又被喚醒標(biāo)記完成后,通知下一階段開始進(jìn)入工作。
對賬結(jié)算(第三階段):在上一階段的數(shù)據(jù)入庫完成后,此階段要做的就是比對每一筆交易是否準(zhǔn)確,一般都是按單號與交易渠道比對交易的金額是否一致,如果金額一致則該筆交易結(jié)算成功,否則將交易判定為異常交易,并入庫處理。由上面的流程分析我們就可以設(shè)計相對合理的CountDownLatch
計數(shù),結(jié)合Semaphore
信號量控制并發(fā)量同時對對比交易單做并發(fā)處理,最終帶所有交易單處理完成后喚醒主線程標(biāo)記對賬完成,并通知下一階段進(jìn)行出賬。
出賬(第四階段):通常平臺在對賬完成后會進(jìn)行出賬,也就是按照平臺的業(yè)務(wù)規(guī)則出具相關(guān)的賬單方便財務(wù)人員進(jìn)行統(tǒng)計。
到此,相信大家對“Java多線程同步工具類CountDownLatch怎么使用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。