最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中CyclicBarrier和CountDownLatch的用法與區(qū)別

 更新時間:2021年08月22日 11:43:29   作者:Deegue  
CyclicBarrier和CountDownLatch這兩個工具都是在java.util.concurrent包下,并且平時很多場景都會使用到。本文將會對兩者進行分析,記錄他們的用法和區(qū)別,感興趣的可以了解一下

前言

CyclicBarrier和CountDownLatch這兩個工具都是在java.util.concurrent包下,并且平時很多場景都會使用到。
本文將會對兩者進行分析,記錄他們的用法和區(qū)別。

CountDownLatch

CountDownLatch是一個非常實用的多線程控制工具類,稱之為“倒計時器”,它允許一個或多個線程一直等待,直到其他線程的操作執(zhí)行完后再執(zhí)行。

CountDownLatch是通過一個計數(shù)器來實現(xiàn)的,計數(shù)器的初始值為線程的數(shù)量。每當(dāng)一個線程完成了自己的任務(wù)后,計數(shù)器的值就會減1。當(dāng)計數(shù)器值到達0時,它表示所有的線程已經(jīng)完成了任務(wù),然后在閉鎖上等待的線程就可以恢復(fù)執(zhí)行任務(wù)。

在這里插入圖片描述

特點

只能一次性使用(不能reset);主線程阻塞;某個線程中斷將永遠到不了屏障點,所有線程都會一直等待。

例子

 	//創(chuàng)建初始化3個線程的線程池
    private ExecutorService                    threadPool     = Executors.newFixedThreadPool(3);
    //保存每個學(xué)生的平均成績
    private ConcurrentHashMap<String, Integer> map            = new ConcurrentHashMap<>();
    private CountDownLatch                     countDownLatch = new CountDownLatch(3);

    private void count() {
        for (int i = 0; i < 3; i++) {
            threadPool.execute(() -> {
                //計算每個學(xué)生的平均成績,代碼略()假設(shè)為60~100的隨機數(shù)
                int score = (int) (Math.random() * 40 + 60);
                try {
                    Thread.sleep(Math.round(Math.random() * 1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                map.put(Thread.currentThread().getName(), score);
                System.out.println(Thread.currentThread().getName() + "同學(xué)的平均成績?yōu)? + score);
                countDownLatch.countDown();
            });
        }
        this.run();
        threadPool.shutdown();
    }

    @Override
    public void run() {
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        int result = 0;
        Set<String> set = map.keySet();
        for (String s : set) {
            result += map.get(s);
        }
        System.out.println("三人平均成績?yōu)?" + (result / 3) + "分");
    }

    public static void main(String[] args) throws InterruptedException {
        long now = System.currentTimeMillis();
        CyclicBarrier1 cb = new CyclicBarrier1();
        cb.count();
        Thread.sleep(100);
        long end = System.currentTimeMillis();
        System.out.println(end - now);
    }

最終輸出結(jié)果:

在這里插入圖片描述

其中1194ms證明了會阻塞主線程。

CyclicBarrier

CyclicBarrier 的字面意思是可循環(huán)使用(Cyclic)的屏障(Barrier)。它要做的事情是,讓一組線程到達一個屏障(也可以叫同步點)時被阻塞,直到最后一個線程到達屏障時,屏障才會開門,所有被屏障攔截的線程才會繼續(xù)干活。

這個屏障之所以用循環(huán)修飾,是因為在所有的線程釋放彼此之后,這個屏障是可以重新使用的(reset()方法重置屏障點),這一點與CountDownLatch不同。

CyclicBarrier是一種同步機制允許一組線程相互等待,等到所有線程都到達一個屏障點才退出await方法,它沒有直接實現(xiàn)AQS而是借助ReentrantLock來實現(xiàn)的同步機制。它是可循環(huán)使用的,而CountDownLatch是一次性的,另外它體現(xiàn)的語義也跟CountDownLatch不同,CountDownLatch減少計數(shù)到達條件采用的是release方式,而CyclicBarrier走向屏障點(await)采用的是Acquire方式,Acquire是會阻塞的,這也實現(xiàn)了CyclicBarrier的另外一個特點,只要有一個線程中斷那么屏障點就被打破,所有線程都將被喚醒(CyclicBarrier自己負責(zé)這部分實現(xiàn),不是由AQS調(diào)度的),這樣也避免了因為一個線程中斷引起永遠不能到達屏障點而導(dǎo)致其他線程一直等待。屏障點被打破的CyclicBarrier將不可再使用(會拋出BrokenBarrierException)除非執(zhí)行reset操作。

構(gòu)造函數(shù)

CyclicBarrier有兩個構(gòu)造函數(shù):

CyclicBarrier(int parties)
int類型的參數(shù)表示有幾個線程來參與這個屏障攔截,(拿上面的例子,即有幾個人跟團旅游);

CyclicBarrier(int parties,Runnable barrierAction)
當(dāng)所有線程到達一個屏障點時,優(yōu)先執(zhí)行barrierAction這個線程。

最重要的一個方法:
await();每個線程調(diào)用await(),表示我已經(jīng)到達屏障點,然后當(dāng)前線程被阻塞。

例子

	//創(chuàng)建初始化3個線程的線程池
    private ExecutorService                    threadPool     = Executors.newFixedThreadPool(3);
    //創(chuàng)建3個CyclicBarrier對象,執(zhí)行完后執(zhí)行當(dāng)前類的run方法
    private CyclicBarrier                      cb             = new CyclicBarrier(3, this);
    //保存每個學(xué)生的平均成績
    private ConcurrentHashMap<String, Integer> map            = new ConcurrentHashMap<>();

    private void count() {
        for (int i = 0; i < 3; i++) {
            threadPool.execute(() -> {
                //計算每個學(xué)生的平均成績,代碼略()假設(shè)為60~100的隨機數(shù)
                int score = (int) (Math.random() * 40 + 60);
                try {
                    Thread.sleep(Math.round(Math.random() * 1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                map.put(Thread.currentThread().getName(), score);
                System.out.println(Thread.currentThread().getName() + "同學(xué)的平均成績?yōu)? + score);
                try {
                    //執(zhí)行完運行await(),等待所有學(xué)生平均成績都計算完畢
                    cb.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            });
        }
        threadPool.shutdown();
    }

    @Override
    public void run() {
        int result = 0;
        Set<String> set = map.keySet();
        for (String s : set) {
            result += map.get(s);
        }
        System.out.println("三人平均成績?yōu)?" + (result / 3) + "分");
    }

    public static void main(String[] args) throws InterruptedException {
        long now = System.currentTimeMillis();
        CyclicBarrier1 cb = new CyclicBarrier1();
        cb.count();
        Thread.sleep(100);
        long end = System.currentTimeMillis();
        System.out.println(end - now);
    }

最終輸出結(jié)果:

在這里插入圖片描述

顯然沒有阻塞主線程。

兩者區(qū)別

  • CountDownLatch的計數(shù)器只能使用一次。而CyclicBarrier的計數(shù)器可以使用reset()
  • 方法重置。所以CyclicBarrier能處理更為復(fù)雜的業(yè)務(wù)場景,比如如果計算發(fā)生錯誤,可以重置計數(shù)器,并讓線程們重新執(zhí)行一次。
  • CyclicBarrier還提供其他有用的方法,比如getNumberWaiting方法可以獲得CyclicBarrier阻塞的線程數(shù)量。isBroken方法用來知道阻塞的線程是否被中斷。比如以下代碼執(zhí)行完之后會返回true。
  • CountDownLatch會阻塞主線程,CyclicBarrier不會阻塞主線程,只會阻塞子線程。
  • 某線程中斷CyclicBarrier會拋出異常,避免了所有線程無限等待。

我們來從jdk作者設(shè)計的目的來看,javadoc是這么描述它們的:

CountDownLatch:
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

CyclicBarrier:
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.

從javadoc的描述可以得出:

CountDownLatch:一個或者多個線程,等待其他多個線程完成某件事情之后才能執(zhí)行;
CyclicBarrier:多個線程互相等待,直到到達同一個同步點,再繼續(xù)一起執(zhí)行。
對于CountDownLatch來說,重點是“一個線程(多個線程)等待”,而其他的N個線程在完成“某件事情”之后,可以終止,也可以等待。而對于CyclicBarrier,重點是多個線程,在任意一個線程沒有完成,所有的線程都必須等待。

CountDownLatch是計數(shù)器,線程完成一個記錄一個,只不過計數(shù)不是遞增而是遞減,而CyclicBarrier更像是一個閥門,需要所有線程都到達,閥門才能打開,然后繼續(xù)執(zhí)行。

到此這篇關(guān)于Java中CyclicBarrier和CountDownLatch的用法與區(qū)別的文章就介紹到這了,更多相關(guān)Java CyclicBarrier CountDownLatch內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot密碼加密的實現(xiàn)示例

    SpringBoot密碼加密的實現(xiàn)示例

    本文主要介紹了SpringBoot密碼加密的實現(xiàn)示例,包括引入依賴、配置加密工具、生成加密密鑰、加密密碼、配置解密,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • spring security登錄成功后跳轉(zhuǎn)回登錄前的頁面

    spring security登錄成功后跳轉(zhuǎn)回登錄前的頁面

    這篇文章主要介紹了spring security登錄成功后跳轉(zhuǎn)回登錄前的頁面,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 關(guān)于springboot響應(yīng)式編程整合webFlux的問題

    關(guān)于springboot響應(yīng)式編程整合webFlux的問題

    在springboot2.x版本中提供了webFlux依賴模塊,該模塊有兩種模型實現(xiàn):一種是基于功能性端點的方式,另一種是基于SpringMVC注解方式,今天通過本文給大家介紹springboot響應(yīng)式編程整合webFlux的問題,感興趣的朋友一起看看吧
    2022-01-01
  • Win10?IDEA如何連接虛擬機中的Hadoop(HDFS)

    Win10?IDEA如何連接虛擬機中的Hadoop(HDFS)

    在虛擬機上配置Hadoop并修改core-site.xml文件,設(shè)置IP為局域網(wǎng)地址,IDEA中創(chuàng)建Maven項目,添加依賴,并檢查Hadoop重啟和端口轉(zhuǎn)發(fā),提供test.bat文件,通過修改IP簡化使用過程
    2024-11-11
  • 深入理解Java定時調(diào)度(Timer)機制

    深入理解Java定時調(diào)度(Timer)機制

    這篇文章主要介紹了深入理解Java定時調(diào)度(Timer)機制,本節(jié)我們主要分析 Timer 的功能。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • Java 模擬cookie登陸簡單操作示例

    Java 模擬cookie登陸簡單操作示例

    這篇文章主要介紹了Java 模擬cookie登陸簡單操作,結(jié)合實例形式分析了Java 模擬cookie登陸的相關(guān)原理與基本實現(xiàn)技巧,需要的朋友可以參考下
    2020-03-03
  • SpringBoot請求響應(yīng)方式示例詳解

    SpringBoot請求響應(yīng)方式示例詳解

    這篇文章主要介紹了SpringBoot請求響應(yīng)的相關(guān)操作,本文通過示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • Java/Android 實現(xiàn)簡單的HTTP服務(wù)器

    Java/Android 實現(xiàn)簡單的HTTP服務(wù)器

    這篇文章主要介紹了Java/Android 如何實現(xiàn)簡單的HTTP服務(wù)器,幫助大家更好的進行功能測試,感興趣的朋友可以了解下
    2020-10-10
  • SpringBoot整合FTP使用示例教程

    SpringBoot整合FTP使用示例教程

    這篇文章主要介紹了SpringBoot整合FTP使用示例教程,本文通過示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • 淺談Spring Boot 開發(fā)REST接口最佳實踐

    淺談Spring Boot 開發(fā)REST接口最佳實踐

    這篇文章主要介紹了淺談Spring Boot 開發(fā)REST接口最佳實踐,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01

最新評論

义马市| 泾源县| 延安市| 保靖县| 云浮市| 赤峰市| 樟树市| 克什克腾旗| 沾益县| 贵定县| 宾川县| 都昌县| 长白| 商丘市| 广东省| 遵义市| 铁岭市| 专栏| 曲沃县| 天台县| 宁河县| 额济纳旗| 新郑市| 望都县| 西乌珠穆沁旗| 呈贡县| 全南县| 宁安市| 和顺县| 教育| 洪湖市| 通化县| 西华县| 马尔康县| 巴青县| 尉氏县| 白水县| 昌乐县| 拜泉县| 天全县| 华池县|