国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

CountDownLatch介紹和使用【Java多線(xiàn)程必備】

這篇具有很好參考價(jià)值的文章主要介紹了CountDownLatch介紹和使用【Java多線(xiàn)程必備】。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

點(diǎn)擊?Mr.綿羊的知識(shí)星球?解鎖更多優(yōu)質(zhì)文章。

目錄

一、介紹

二、特性

三、實(shí)現(xiàn)原理

四、適用場(chǎng)景

五、注意事項(xiàng)

六、實(shí)際應(yīng)用


一、介紹

? ? CountDownLatch?是 Java 中的一個(gè)并發(fā)工具類(lèi),用于協(xié)調(diào)多個(gè)線(xiàn)程之間的同步。其作用是讓某一個(gè)線(xiàn)程等待多個(gè)線(xiàn)程的操作完成之后再執(zhí)行。它可以使一個(gè)或多個(gè)線(xiàn)程等待一組事件的發(fā)生,而其他的線(xiàn)程則可以觸發(fā)這組事件。

二、特性

1. CountDownLatch?可以用于控制一個(gè)或多個(gè)線(xiàn)程等待多個(gè)任務(wù)完成后再執(zhí)行。

2. CountDownLatch?的計(jì)數(shù)器只能夠被減少,不能夠被增加。

3. CountDownLatch?的計(jì)數(shù)器初始值為正整數(shù),每次調(diào)用?countDown()?方法會(huì)將計(jì)數(shù)器減 1,計(jì)數(shù)器為 0 時(shí),等待線(xiàn)程開(kāi)始執(zhí)行。

三、實(shí)現(xiàn)原理

? ? CountDownLatch?的實(shí)現(xiàn)原理比較簡(jiǎn)單,它主要依賴(lài)于?AQS(AbstractQueuedSynchronizer)框架來(lái)實(shí)現(xiàn)線(xiàn)程的同步。

? ? CountDownLatch?內(nèi)部維護(hù)了一個(gè)計(jì)數(shù)器,該計(jì)數(shù)器初始值為?N,代表需要等待的線(xiàn)程數(shù)目,當(dāng)一個(gè)線(xiàn)程完成了需要等待的任務(wù)后,就會(huì)調(diào)用?countDown()?方法將計(jì)數(shù)器減 1,當(dāng)計(jì)數(shù)器的值為 0 時(shí),等待的線(xiàn)程就會(huì)開(kāi)始執(zhí)行。

四、適用場(chǎng)景

1. 主線(xiàn)程等待多個(gè)子線(xiàn)程完成任務(wù)后再繼續(xù)執(zhí)行。例如:一個(gè)大型的任務(wù)需要被拆分成多個(gè)子任務(wù)并交由多個(gè)線(xiàn)程并行處理,等所有子任務(wù)都完成后再將處理結(jié)果進(jìn)行合并。

2. 啟動(dòng)多個(gè)線(xiàn)程并發(fā)執(zhí)行任務(wù),等待所有線(xiàn)程執(zhí)行完畢后進(jìn)行結(jié)果匯總。例如:在一個(gè)并發(fā)請(qǐng)求量比較大的 Web 服務(wù)中,可以使用?CountDownLatch?控制多個(gè)線(xiàn)程同時(shí)處理請(qǐng)求,等待所有線(xiàn)程處理完畢后將結(jié)果進(jìn)行匯總。

3. 線(xiàn)程 A 等待線(xiàn)程 B 執(zhí)行完某個(gè)任務(wù)后再執(zhí)行自己的任務(wù)。例如:在分布式系統(tǒng)中,一個(gè)節(jié)點(diǎn)需要等待其他節(jié)點(diǎn)的加入后才能執(zhí)行某個(gè)任務(wù),可以使用?CountDownLatch?控制節(jié)點(diǎn)的加入,等所有節(jié)點(diǎn)都加入完成后再執(zhí)行任務(wù)。

4. 多個(gè)線(xiàn)程等待一個(gè)共享資源的初始化完成后再進(jìn)行操作。例如:在某個(gè)資源初始化較慢的系統(tǒng)中,可以使用?CountDownLatch?控制多個(gè)線(xiàn)程等待共享資源初始化完成后再進(jìn)行操作。

CountDownLatch?適用于多線(xiàn)程任務(wù)的協(xié)同處理場(chǎng)景,能夠有效提升多線(xiàn)程任務(wù)的執(zhí)行效率,同時(shí)也能夠降低多線(xiàn)程任務(wù)的復(fù)雜度和出錯(cuò)率。

五、注意事項(xiàng)

1. CountDownLatch?對(duì)象的計(jì)數(shù)器只能減不能增,即一旦計(jì)數(shù)器為 0,就無(wú)法再重新設(shè)置為其他值,因此在使用時(shí)需要根據(jù)實(shí)際需要設(shè)置初始值。

2. CountDownLatch?的計(jì)數(shù)器是線(xiàn)程安全的,多個(gè)線(xiàn)程可以同時(shí)調(diào)用?countDown()?方法,而不會(huì)產(chǎn)生沖突。

3. 如果?CountDownLatch?的計(jì)數(shù)器已經(jīng)為 0,再次調(diào)用?countDown()?方法也不會(huì)產(chǎn)生任何效果。

4. 如果在等待過(guò)程中,有線(xiàn)程發(fā)生異常或被中斷,計(jì)數(shù)器的值可能不會(huì)減少到 0,因此在使用時(shí)需要根據(jù)實(shí)際情況進(jìn)行異常處理。

5. CountDownLatch?可以與其他同步工具(如?Semaphore、CyclicBarrier)結(jié)合使用,實(shí)現(xiàn)更復(fù)雜的多線(xiàn)程同步。

六、實(shí)際應(yīng)用

1. 案例一

? ? (1) 場(chǎng)景

? ? 一個(gè)簡(jiǎn)單的?CountDownLatch?示例,演示了如何使用?CountDownLatch?實(shí)現(xiàn)多個(gè)線(xiàn)程的同步。

? ? (2) 代碼

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * CountDownLatchCase1
 * 如何使用CountDownLatch實(shí)現(xiàn)多個(gè)線(xiàn)程的同步。
 *
 * @author wxy
 * @since 2023-04-18
 */
public class CountDownLatchCase1 {
    private static final Logger LOGGER = LoggerFactory.getLogger(CountDownLatchCase1.class);

    public static void main(String[] args) throws InterruptedException {
        // 創(chuàng)建 CountDownLatch 對(duì)象,需要等待 3 個(gè)線(xiàn)程完成任務(wù)
        CountDownLatch latch = new CountDownLatch(3);

        // 創(chuàng)建 3 個(gè)線(xiàn)程
        Worker worker1 = new Worker(latch, "worker1");
        Worker worker2 = new Worker(latch, "worker2");
        Worker worker3 = new Worker(latch, "worker3");

        // 啟動(dòng) 3 個(gè)線(xiàn)程
        worker1.start();
        worker2.start();
        worker3.start();

        // 等待 3 個(gè)線(xiàn)程完成任務(wù)
        latch.await();

        // 所有線(xiàn)程完成任務(wù)后,執(zhí)行下面的代碼
        LOGGER.info("All workers have finished their jobs!");
    }
}

class Worker extends Thread {
    private static final Logger LOGGER = LoggerFactory.getLogger(Worker.class);

    private final CountDownLatch latch;

    public String name;

    public Worker(CountDownLatch latch, String name) {
        this.latch = latch;
        this.name = name;
    }

    @Override
    public void run() {
        try {
            // 模擬任務(wù)耗時(shí)
            TimeUnit.MILLISECONDS.sleep(1000);
            LOGGER.info("{} has finished the job!", name);
        } catch (InterruptedException e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            // 一定要保證每個(gè)線(xiàn)程執(zhí)行完畢或者異常后調(diào)用countDown()方法
            // 如果不調(diào)用會(huì)導(dǎo)致其他線(xiàn)程一直等待, 無(wú)法繼續(xù)執(zhí)行
            // 建議放在finally代碼塊中, 防止異常情況下未調(diào)用countDown()方法
            latch.countDown();
        }
    }
}

運(yùn)行結(jié)果:

countdownlatch,Java,多線(xiàn)程必備,java

? ? 在上面的代碼中,首先創(chuàng)建了一個(gè)CountDownLatch對(duì)象,并指定需要等待的線(xiàn)程數(shù)為 3。然后創(chuàng)建了 3 個(gè)線(xiàn)程并啟動(dòng)。每個(gè)線(xiàn)程會(huì)模擬執(zhí)行一個(gè)耗時(shí)的任務(wù),執(zhí)行完成后會(huì)調(diào)用?countDown()?方法將計(jì)數(shù)器減 1。在所有線(xiàn)程都完成任務(wù)后,主線(xiàn)程會(huì)執(zhí)行?latch.await()?方法等待計(jì)數(shù)器為 0,然后輸出所有線(xiàn)程都完成任務(wù)的提示信息。

? ? 思考:如果不使用CountDownLatch情況將會(huì)是怎樣呢?

? ? 運(yùn)行結(jié)果:

countdownlatch,Java,多線(xiàn)程必備,java

? ? 由執(zhí)行結(jié)果可知,主線(xiàn)程不會(huì)等待子線(xiàn)程結(jié)束后再執(zhí)行。如果我們主線(xiàn)程(main) 需要其他線(xiàn)程執(zhí)行后的結(jié)果,我們就需要使用countDownLantch讓主線(xiàn)程和執(zhí)行快的線(xiàn)程等待子線(xiàn)程全部執(zhí)行完畢再向下執(zhí)行。

? ? 思考:如果某個(gè)線(xiàn)程漏調(diào)用.countDown();會(huì)怎么樣呢?

? ? 接下來(lái)我們模擬worker1線(xiàn)程異常,如果該線(xiàn)程異常latch.countDown()方法就無(wú)法被調(diào)用。

public void run() {
    try {
        // 模擬任務(wù)耗時(shí)
        if ("worker1".equals(name)) {
            throw new RuntimeException(name + "運(yùn)行異常");
        }
        TimeUnit.MILLISECONDS.sleep(1000);
        LOGGER.info("{} has finished the job!", name);
        latch.countDown();
    } catch (InterruptedException e) {
        LOGGER.error(e.getMessage(), e);
    }
}

? ? 運(yùn)行結(jié)果:

countdownlatch,Java,多線(xiàn)程必備,java

? ? 由運(yùn)行結(jié)果可知,當(dāng)worker1線(xiàn)程由于異常沒(méi)有執(zhí)行countDown()方法,最后state結(jié)果不為0,導(dǎo)致所有線(xiàn)程停在AQS中自旋(死循環(huán))。所以程序無(wú)法結(jié)束。(如何解決這個(gè)問(wèn)題呢?請(qǐng)看案例二)

countdownlatch,Java,多線(xiàn)程必備,java

2. 案例二

? ? (1) 場(chǎng)景

? ? 當(dāng)年剛工作不久,遇到一個(gè)這樣的問(wèn)題:遠(yuǎn)程調(diào)用某個(gè)api,大部分情況下需要2-3s才能讀取到響應(yīng)值。我需要解析響應(yīng)的JSON用于后續(xù)的操作。由于這個(gè)調(diào)用是異步的,我沒(méi)辦法在主線(xiàn)程獲取到響應(yīng)的JSON值。

? ? 當(dāng)時(shí)第一時(shí)間想到的是讓主線(xiàn)程休眠,但是休眠多久好呢?1、2、3s?顯然是不行的,如果1s就請(qǐng)求成功并響應(yīng)了,你要等3s,這不是浪費(fèi)時(shí)間嗎!

? ? 于是,我就請(qǐng)教了公司一位大佬。他告訴我使用CountDownLatch。我恍然大悟,之前自己學(xué)過(guò),但是一到戰(zhàn)場(chǎng)上我就把他給忘記了(實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn))。

(2) 代碼(偷個(gè)懶 哈哈 就是在案例一的代碼中修改了await()方法)

? ? 將latch.await()修改為 latch.await(5, TimeUnit.SECONDS),這段代碼啥意思呢?就是當(dāng)?shù)谝粋€(gè)線(xiàn)程到達(dá)await()方法開(kāi)始計(jì)時(shí),5s后不等待未執(zhí)行完畢的線(xiàn)程,直接向下執(zhí)行。這么寫(xiě)的好處是,當(dāng)調(diào)用某個(gè)方法超時(shí)太久,不影響我們的主邏輯。(很實(shí)用)

// 等待 3 個(gè)線(xiàn)程完成任務(wù)
if (!latch.await(5, TimeUnit.SECONDS)) {
    LOGGER.warn("{} time out", worker1.name);
}

// 所有線(xiàn)程完成任務(wù)后,執(zhí)行下面的代碼
LOGGER.info("all workers have finished their jobs!");

? ? 看一下加了latch.await(5, TimeUnit.SECONDS)方法后執(zhí)行結(jié)果:

countdownlatch,Java,多線(xiàn)程必備,java文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-743696.html

到了這里,關(guān)于CountDownLatch介紹和使用【Java多線(xiàn)程必備】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 巧用CountDownLatch實(shí)現(xiàn)多線(xiàn)程并行工作

    【前言】 ????? CountDownLatch 是JDK提供的一個(gè)同步工具,它可以讓一個(gè)或多個(gè)線(xiàn)程掛起等待,一直等到其他線(xiàn)程執(zhí)行完成才會(huì)繼續(xù)執(zhí)行。常用方法有 countDown 方法和 await 方法, CountDownLatch 在初始化時(shí),需要指定一個(gè)整數(shù)n作為計(jì)數(shù)器。當(dāng)調(diào)用 countDown 方法時(shí),計(jì)數(shù)器會(huì)被減1;

    2024年02月13日
    瀏覽(20)
  • 性能優(yōu)化實(shí)戰(zhàn)使用CountDownLatch

    1.分析問(wèn)題 原程序是分頁(yè)查詢(xún)EventAffinityScoreDO表的數(shù)據(jù),每次獲取2000條在一個(gè)個(gè)遍歷去更新EventAffinityScoreDO表的數(shù)據(jù)。但是這樣耗時(shí)比較慢,測(cè)試過(guò)30萬(wàn)的數(shù)據(jù)需要2小時(shí) 單個(gè)線(xiàn)程一個(gè)個(gè)遍歷去更新表數(shù)據(jù)太慢了,我想把2000的數(shù)據(jù)分成多份,每份200條,可以分成10份。每份用一

    2024年02月07日
    瀏覽(14)
  • ListenableFuture和countdownlatch使用example

    ListenableFuture可以允許你注冊(cè)回調(diào)方法(callbacks),在運(yùn)算(多線(xiàn)程執(zhí)行)完成的時(shí)候進(jìn)行調(diào)用, 或者在運(yùn)算(多線(xiàn)程執(zhí)行)完成后立即執(zhí)行

    2024年02月07日
    瀏覽(20)
  • 5.5. Java并發(fā)工具類(lèi)(如CountDownLatch、CyclicBarrier等)

    5.5. Java并發(fā)工具類(lèi)(如CountDownLatch、CyclicBarrier等)

    5.5.1 CountDownLatch CountDownLatch 是一個(gè)同步輔助類(lèi),它允許一個(gè)或多個(gè)線(xiàn)程等待,直到其他線(xiàn)程完成一組操作。 CountDownLatch 有一個(gè)計(jì)數(shù)器,當(dāng)計(jì)數(shù)器減為0時(shí),等待的線(xiàn)程將被喚醒。計(jì)數(shù)器只能減少,不能增加。 示例:使用CountDownLatch等待所有線(xiàn)程完成任務(wù) 假設(shè)我們有一個(gè)任務(wù)需

    2024年02月07日
    瀏覽(23)
  • CountDownLatch倒計(jì)時(shí)器源碼解讀與使用

    CountDownLatch倒計(jì)時(shí)器源碼解讀與使用

    ??? 個(gè)人主頁(yè) :牽著貓散步的鼠鼠? ??? 系列專(zhuān)欄 :Java全棧-專(zhuān)欄 ??? 個(gè)人學(xué)習(xí)筆記,若有缺誤,歡迎評(píng)論區(qū)指正 ? 目錄 1. 前言 2. CountDownLatch有什么用 3. CountDownLatch底層原理 3.1. countDown()方法 3.2.?await()方法 4. CountDownLatch的基本使用 5. 總結(jié) 在很多的面經(jīng)中都看到過(guò)提問(wèn)

    2024年04月22日
    瀏覽(22)
  • keycloak~CountDownLatch在keycloak中的使用

    在Java中, CountDownLatch 是一個(gè)線(xiàn)程同步的輔助類(lèi),用于等待其他線(xiàn)程完成操作。如果 CountDownLatch 實(shí)例被丟失或無(wú)法訪問(wèn),可能會(huì)導(dǎo)致無(wú)法正常使用該對(duì)象。這可能會(huì)導(dǎo)致等待線(xiàn)程永遠(yuǎn)處于等待狀態(tài),無(wú)法繼續(xù)執(zhí)行。 如果意外丟失了 CountDownLatch 對(duì)象,你可以嘗試以下方法進(jìn)行

    2024年02月09日
    瀏覽(22)
  • CountDownLatch

    這個(gè)類(lèi)是在java.util.concurrent并發(fā)包里面 允許一個(gè)或者多個(gè)線(xiàn)程一直等待,直到其他線(xiàn)程執(zhí)行完成后再執(zhí)行 舉例:班長(zhǎng)和5名同學(xué)都在教室里面寫(xiě)作業(yè),班長(zhǎng)必須等五個(gè)同學(xué)都走了之后,才能把教師門(mén)的鎖鎖上 這是通過(guò)一個(gè)計(jì)數(shù)器來(lái)實(shí)現(xiàn)的,計(jì)數(shù)器初始化的值為線(xiàn)程的數(shù)量,每

    2024年02月06日
    瀏覽(16)
  • CountDownLatch用法詳解

    CountDownLatch用法詳解

    深入理解CountDownLatch計(jì)數(shù)器 線(xiàn)程計(jì)數(shù)器 用于線(xiàn)程執(zhí)行任務(wù),計(jì)數(shù) 等待線(xiàn)程結(jié)束 用法一: 等待所有的事情都做完 始終是2個(gè)線(xiàn)程在做事情,等2個(gè)線(xiàn)程做完事情才會(huì)停止下來(lái)。 用法二:假設(shè)2個(gè)線(xiàn)程做事情,剛開(kāi)始并行做事情,等一個(gè)執(zhí)行完成之后,另一個(gè)才能執(zhí)行( 實(shí)際還是計(jì)數(shù) )

    2023年04月19日
    瀏覽(13)
  • CompletableFuture真香,可以替代CountDownLatch!

    CompletableFuture真香,可以替代CountDownLatch!

    之前我們提到了 Future 和 Promise。Future 相當(dāng)于一個(gè)占位符,代表一個(gè)操作將來(lái)的結(jié)果。一般通過(guò) get 可以直接阻塞得到結(jié)果,或者讓它異步執(zhí)行然后通過(guò) callback 回調(diào)結(jié)果。 但如果回調(diào)中嵌入了回調(diào)呢?如果層次很深,就是回調(diào)地獄。 Java 中的 CompletableFuture 其實(shí)就是 Promise,用

    2024年02月08日
    瀏覽(15)
  • 19.詳解AQS家族的成員:CountDownLatch

    19.詳解AQS家族的成員:CountDownLatch

    關(guān)注王有志,一個(gè)分享硬核Java技術(shù)的互金摸魚(yú)俠 歡迎你加入 Java人的提桶跑路群 :共同富裕的Java人 今天我們來(lái)聊一聊AQS家族中的另一個(gè)重要成員CountDownLatch。關(guān)于CountDownLatch的面試題并不多,除了問(wèn)“是什么”和“如何實(shí)現(xiàn)的“外,CountDownLatch還會(huì)和CyclicBarrier進(jìn)行對(duì)比: 什

    2024年02月08日
    瀏覽(13)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包