欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java使用CountDownLatch實現(xiàn)多線程協(xié)作

 更新時間:2023年11月07日 10:55:46   作者:FirstMrRight  
在多線程編程中,經(jīng)常需要實現(xiàn)一種機制來協(xié)調(diào)多個線程的執(zhí)行,以確保某些操作在所有線程完成后再進(jìn)行,CountDownLatch?就是?Java?并發(fā)包中提供的一種同步工具,下面我們就來看看如何使用CountDownLatch實現(xiàn)多線程協(xié)作吧

前言

在多線程編程中,經(jīng)常需要實現(xiàn)一種機制來協(xié)調(diào)多個線程的執(zhí)行,以確保某些操作在所有線程完成后再進(jìn)行。CountDownLatch 就是 Java 并發(fā)包中提供的一種同步工具,它能夠讓一個或多個線程等待其他線程完成操作。

了解 CountDownLatch

概括

CountDownLatch 是Java 1.5版本推出的一個同步輔助類,在構(gòu)造時需要指定一個計數(shù)值,該計數(shù)值表示需要等待的事件數(shù)量。每當(dāng)一個事件完成時,計數(shù)值就會減一,當(dāng)計數(shù)值減至零時,等待的線程就會被喚醒繼續(xù)執(zhí)行。

CountDownLatch 的應(yīng)用場景

CountDownLatch 可以被廣泛應(yīng)用于各種多線程協(xié)作的場景,例如:

  • 主線程等待多個子線程完成后再執(zhí)行下一步操作。
  • 多個子任務(wù)并行執(zhí)行,最后合并結(jié)果。
  • 并行計算中,等待所有計算任務(wù)完成后進(jìn)行統(tǒng)一匯總。

使用案例

讓我們通過一個示例代碼來理解 CountDownLatch 的使用。假設(shè)有一個任務(wù)需要被分配給多個子線程來完成,并且主線程需要等待所有子線程執(zhí)行完畢后才能繼續(xù)執(zhí)行。

//任務(wù)分割的線程數(shù)
private static final int THREAD_TOTAL = 10;

//子線程執(zhí)行的超時時間
private static final int countDownLatchTimeout = 5;

public static void main(String[] args) {
    //創(chuàng)建CountDownLatch并設(shè)置計數(shù)值,該count值可以根據(jù)線程數(shù)的需要設(shè)置
    CountDownLatch countDownLatch = new CountDownLatch(THREAD_TOTAL);

    //創(chuàng)建線程池,開啟、創(chuàng)建異步線程執(zhí)行任務(wù)
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    for (int i = 0; i < THREAD_TOTAL; i++) {
        cachedThreadPool.execute(() -> {
            try {
                Thread.sleep(5000);
                System.out.println(Thread.currentThread().getName() + " do something!");
            } catch (Exception e) {
                System.out.println("Exception: do something exception");
            } finally {
                //該線程執(zhí)行完畢-1
                countDownLatch.countDown();
            }
        });
    }

    //回到主線程中
    System.out.println("Back main thread do something");
    try {
        //主線程等待線程池中完成(子線程執(zhí)行超時時間)
        boolean await = countDownLatch.await(countDownLatchTimeout, TimeUnit.MINUTES);
        System.out.println(await);
    } catch (InterruptedException e) {
        System.out.println("Exception: await interrupted exception");
    } finally {
        System.out.println("countDownLatch: " + countDownLatch);
    }
    System.out.println("main thread do something-2");
}

CountDownLatch 的優(yōu)缺點分析

優(yōu)點

  • 簡單易用:CountDownLatch 的使用非常簡單,通過 await 和 countDown 方法即可實現(xiàn)多線程的協(xié)作。
  • 靈活性:可以根據(jù)具體場景指定等待的計數(shù)值,可以靈活控制多個線程的協(xié)作關(guān)系。
  • 高效性:底層使用了 AQS(AbstractQueuedSynchronizer)來實現(xiàn)同步,能夠保證高效地協(xié)調(diào)多個線程的執(zhí)行順序。

缺點

  • 一次性:CountDownLatch 的計數(shù)值只能減少,無法重置。一旦計數(shù)值減至零,就不能再次使用。
  • 無法中途取消:一旦等待開始,就無法中途取消等待,除非等待超時或者發(fā)生中斷。

如果您學(xué)有余力或手頭沒有著急的需求,請繼續(xù)往下看,讓我們簡單從源碼層面分析下CountDownLatch的實現(xiàn)。

從源碼層面分析CountDownLatch的實現(xiàn)

實現(xiàn)

我截取了CountDownLatch內(nèi)部關(guān)鍵實現(xiàn)邏輯來分析其實現(xiàn)原理:

CountDownLatch的功能主要通過內(nèi)部類Sync實現(xiàn),在內(nèi)部類中,Sync繼承自AbstractQueuedSynchronizer來實現(xiàn)同步操作,AbstractQueuedSynchronizer提供了同步器實現(xiàn)的基礎(chǔ)框架,通過該類,開發(fā)者可以相對容易地實現(xiàn)自定義的同步器,例如獨占鎖、共享鎖、信號量等。

/**
 * Synchronization control For CountDownLatch.
 * Uses AQS state to represent count.
 */
private static final class Sync extends AbstractQueuedSynchronizer {
    private static final long serialVersionUID = 4982264981922014374L;

    Sync(int count) {
        setState(count);
    }

    int getCount() {
        return getState();
    }

    protected int tryAcquireShared(int acquires) {
        return (getState() == 0) ? 1 : -1;
    }

    protected boolean tryReleaseShared(int releases) {
        // Decrement count; signal when transition to zero
        for (;;) {
            int c = getState();
            if (c == 0)
                return false;
            int nextc = c-1;
            if (compareAndSetState(c, nextc))
                return nextc == 0;
        }
    }
}

private final Sync sync;


public CountDownLatch(int count) {
    if (count < 0) throw new IllegalArgumentException("count < 0");
    this.sync = new Sync(count);
}


public void await() throws InterruptedException {
    sync.acquireSharedInterruptibly(1);
}
  • Sync :定義了一個名為 Sync 的靜態(tài)內(nèi)部類,它繼承自 AbstractQueuedSynchronizer 類,這個類通常被用于實現(xiàn)鎖和相關(guān)的同步器。
  • count:定義了一個序列化版本號,用于在對象序列化和反序列化時進(jìn)行版本控制。同時count在CountDownLatch的構(gòu)造方法中用于設(shè)置當(dāng)前狀態(tài),即:編碼人員傳入的計數(shù)值。
  • getCount:獲取當(dāng)前狀態(tài)值,即剩余的計數(shù)值。
  • tryAcquireShared:嘗試獲取共享資源,如果當(dāng)前狀態(tài)為0,則返回1表示成功獲取資源,否則返回-1表示獲取資源失敗。

tryReleaseShared

protected boolean tryReleaseShared(int releases) {
    // Decrement count; signal when transition to zero
    for (;;) {
        int c = getState();
        if (c == 0)
            return false;
        int nextc = c-1;
        if (compareAndSetState(c, nextc))
            return nextc == 0;
    }
}

tryReleaseShared 方法嘗試釋放共享資源,首先通過一個無限循環(huán)不斷嘗試,在循環(huán)中獲取當(dāng)前狀態(tài)值,如果狀態(tài)值已經(jīng)為0,則直接返回false;否則將狀態(tài)值減1,并嘗試原子性地設(shè)置狀態(tài)值,如果設(shè)置成功,則返回是否狀態(tài)值變?yōu)?,否則繼續(xù)循環(huán)。

總的來說,這段代碼實現(xiàn)了一個簡單的 CountDownLatch 功能,通過 tryAcquireShared 方法嘗試獲取共享資源,通過 tryReleaseShared 方法嘗試釋放共享資源。當(dāng)共享資源的狀態(tài)值為0時,表示所有等待的線程都已被釋放。

擴展

CompletableFuture簡述

在JDK 1.8后,java.util.concurrent包提供了CompletableFuture類用于支持異步編程和異步任務(wù)的處理,相較于CountDownLatch,它提供了更豐富的API,就個人而言,我更喜歡CompletableFuture,因為它擴展性強,更適合JDK 8提供的函數(shù)式編程特性,代碼更加優(yōu)雅。

CompletableFuture 的優(yōu)缺點

優(yōu)點

  • 功能強大:CompletableFuture 提供了豐富的方法和組合操作,可以實現(xiàn)復(fù)雜的異步編程邏輯。
  • 支持異常處理:可以通過 exceptionally 或 handle 方法方便地處理異步操作中的異常情況。
  • 支持組合操作:可以通過 thenCompose、thenCombine 等方法方便地進(jìn)行多個 CompletableFuture 的組合操作。

缺點

  • 學(xué)習(xí)曲線較陡:相對于 CountDownLatch,CompletableFuture 的使用可能需要更多的學(xué)習(xí)和理解異步編程的概念。
  • 復(fù)雜度較高:在復(fù)雜的業(yè)務(wù)場景下,可能會出現(xiàn)嵌套回調(diào)、異常處理困難等問題,增加了代碼的復(fù)雜度。

總結(jié)

CountDownLatch 和 CompletableFuture 都是 Java 中用于多線程協(xié)作的工具,它們各自適用于不同的場景。CountDownLatch 更適合簡單的多線程協(xié)作,而 CompletableFuture 則更適合復(fù)雜的異步編程場景。在實際應(yīng)用中,我們可以根據(jù)具體的需求選擇合適的工具來實現(xiàn)多線程協(xié)作和異步編程,以達(dá)到更好的開發(fā)效率和代碼質(zhì)量。

以上就是java使用CountDownLatch實現(xiàn)多線程協(xié)作的詳細(xì)內(nèi)容,更多關(guān)于java CountDownLatch的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot統(tǒng)一數(shù)據(jù)返回的幾種方式

    SpringBoot統(tǒng)一數(shù)據(jù)返回的幾種方式

    在Web應(yīng)用程序開發(fā)中,統(tǒng)一數(shù)據(jù)返回格式對于前后端分離項目尤為重要,本文就來介紹一下SpringBoot統(tǒng)一數(shù)據(jù)返回的幾種方式,具有一定的參考價值,感興趣的可以了解一下
    2024-07-07
  • Java交換map的key和value值的步驟和代碼示例

    Java交換map的key和value值的步驟和代碼示例

    在Java中,我們都知道直接交換Map的key和value是不被允許的,因為Map的接口設(shè)計是基于key-value對的,其中key是唯一的,并且是不可變的,所以本文給大家介紹了Java交換map的key和value值的步驟和代碼示例,需要的朋友可以參考下
    2024-09-09
  • SSM如何實現(xiàn)在Controller中添加事務(wù)管理

    SSM如何實現(xiàn)在Controller中添加事務(wù)管理

    這篇文章主要介紹了SSM如何實現(xiàn)在Controller中添加事務(wù)管理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java調(diào)用Deepseek實現(xiàn)項目代碼審查

    Java調(diào)用Deepseek實現(xiàn)項目代碼審查

    這篇文章主要為大家詳細(xì)介紹了Java如何調(diào)用Deepseek實現(xiàn)項目代碼審查功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02
  • java?Object轉(zhuǎn)Integer實現(xiàn)方式

    java?Object轉(zhuǎn)Integer實現(xiàn)方式

    這篇文章主要介紹了java?Object轉(zhuǎn)Integer實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • java實現(xiàn)快速排序的方法

    java實現(xiàn)快速排序的方法

    這篇文章主要介紹了java實現(xiàn)快速排序的方法,涉及java排序的相關(guān)操作技巧,需要的朋友可以參考下
    2015-05-05
  • IDEA編譯報錯:Error:java:無效的源發(fā)行版:17的解決辦法

    IDEA編譯報錯:Error:java:無效的源發(fā)行版:17的解決辦法

    IDEA里面裝了幾個版本的JDK,導(dǎo)入工程后時不時提示一下錯誤,下面這篇文章主要給大家介紹了關(guān)于IDEA編譯報錯:Error:java:無效的源發(fā)行版:17的解決辦法,需要的朋友可以參考下
    2023-01-01
  • java中抽象類和接口的相同和不同點介紹

    java中抽象類和接口的相同和不同點介紹

    大家好,本篇文章主要講的是java中抽象類和接口的相同和不同點介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 詳解spring與shiro集成

    詳解spring與shiro集成

    這篇文章主要介紹了詳解spring與shiro集成,需要的朋友可以參考下
    2017-09-09
  • SpringBoot操作Mongodb的實現(xiàn)示例

    SpringBoot操作Mongodb的實現(xiàn)示例

    本文主要介紹了SpringBoot操作Mongodb的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評論