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

Java并發(fā)編程中的CyclicBarrier線程屏障詳解

 更新時(shí)間:2023年12月27日 08:52:35   作者:緣來(lái)如此09  
這篇文章主要介紹了Java并發(fā)編程中的CyclicBarrier線程屏障詳解,

一、簡(jiǎn)介

CyclicBarrier的字面意思是可循環(huán)使用(Cyclic)的屏障(Barrier)。它要做的事情是,讓一組線程到達(dá)一個(gè)屏障(也可以叫同步點(diǎn))時(shí)被阻塞,直到最后一個(gè)線程到達(dá)屏障時(shí),屏障才會(huì)開(kāi)門,所有被屏障攔截的線程才會(huì)繼續(xù)運(yùn)行。下圖演示了這一過(guò)程。

二、與countdownlatch的區(qū)別

它的主要作用其實(shí)和CountDownLanch差不多,都是讓一組線程到達(dá)一個(gè)屏障時(shí)被阻塞,直到最后一個(gè)線程到達(dá)屏障時(shí),屏障會(huì)被打開(kāi),所有被屏障阻塞的線程才會(huì)繼續(xù)執(zhí)行,不過(guò)它是可以循環(huán)執(zhí)行的,這是它與CountDownLanch最大的不同。

cyclicbarrier-2

三、核心參數(shù)

 /** The lock for guarding barrier entry */
    // 可重入鎖
    private final ReentrantLock lock = new ReentrantLock();
    /** Condition to wait on until tripped */
    // 條件隊(duì)列,具體看AQS
    private final Condition trip = lock.newCondition();
    /** The number of parties */
    // 參與的線程數(shù)量
    private final int parties;
    /* The command to run when tripped */
    // 由最后一個(gè)進(jìn)入 barrier 的線程執(zhí)行的操作
    private final Runnable barrierCommand;
    /** The current generation */
    // 當(dāng)前代
    private Generation generation = new Generation();
    // 正在等待進(jìn)入屏障的線程數(shù)量
    private int count;

四、構(gòu)造方法

public CyclicBarrier(int parties, Runnable barrierAction) {
        // 參與的線程數(shù)量小于等于0,拋出異常
        if (parties <= 0) throw new IllegalArgumentException();
        // 設(shè)置parties
        this.parties = parties;
        // 設(shè)置count
        this.count = parties;
        // 設(shè)置barrierCommand
        this.barrierCommand = barrierAction;
    }

該構(gòu)造函數(shù)可以指定關(guān)聯(lián)該CyclicBarrier的線程數(shù)量,并且可以指定在所有線程都進(jìn)入屏障后的執(zhí)行動(dòng)作,該執(zhí)行動(dòng)作由最后一個(gè)進(jìn)行屏障的線程執(zhí)行。

五、核心方法

await方法

(1)dowait方法

await中調(diào)用dowait
private int dowait(boolean timed, long nanos)
        throws InterruptedException, BrokenBarrierException,
               TimeoutException {
        // 保存當(dāng)前鎖
        final ReentrantLock lock = this.lock;
        // 鎖定
        lock.lock();
        try {
            // 保存當(dāng)前代
            final Generation g = generation;
            if (g.broken) // 屏障被破壞,拋出異常
                throw new BrokenBarrierException();
            if (Thread.interrupted()) { // 線程被中斷
                // 損壞當(dāng)前屏障,并且喚醒所有的線程,只有擁有鎖的時(shí)候才會(huì)調(diào)用
                breakBarrier();
                // 拋出異常
                throw new InterruptedException();
            }
            // 減少正在等待進(jìn)入屏障的線程數(shù)量
            int index = --count;
            if (index == 0) {  // 正在等待進(jìn)入屏障的線程數(shù)量為0,所有線程都已經(jīng)進(jìn)入
                // 運(yùn)行的動(dòng)作標(biāo)識(shí)
                boolean ranAction = false;
                try {
                    // 保存運(yùn)行動(dòng)作
                    final Runnable command = barrierCommand;
                    if (command != null) // 動(dòng)作不為空
                        // 運(yùn)行
                        command.run();
                    // 設(shè)置ranAction狀態(tài)
                    ranAction = true;
                    // 進(jìn)入下一代
                    nextGeneration();
                    return 0;
                } finally {
                    if (!ranAction) // 沒(méi)有運(yùn)行的動(dòng)作
                        // 損壞當(dāng)前屏障
                        breakBarrier();
                }
            }
            // loop until tripped, broken, interrupted, or timed out
            // 無(wú)限循環(huán)
            for (;;) {
                try {
                    if (!timed) // 沒(méi)有設(shè)置等待時(shí)間
                        // 等待
                        trip.await(); 
                    else if (nanos > 0L) // 設(shè)置了等待時(shí)間,并且等待時(shí)間大于0
                        // 等待指定時(shí)長(zhǎng)
                        nanos = trip.awaitNanos(nanos);
                } catch (InterruptedException ie) { 
                    if (g == generation && ! g.broken) { // 等于當(dāng)前代并且屏障沒(méi)有被損壞
                        // 損壞當(dāng)前屏障
                        breakBarrier();
                        // 拋出異常
                        throw ie;
                    } else { // 不等于當(dāng)前帶后者是屏障被損壞
                        // We're about to finish waiting even if we had not
                        // been interrupted, so this interrupt is deemed to
                        // "belong" to subsequent execution.
                        // 中斷當(dāng)前線程
                        Thread.currentThread().interrupt();
                    }
                }
                if (g.broken) // 屏障被損壞,拋出異常
                    throw new BrokenBarrierException();
                if (g != generation) // 不等于當(dāng)前代
                    // 返回索引
                    return index;
                if (timed && nanos <= 0L) { // 設(shè)置了等待時(shí)間,并且等待時(shí)間小于0
                    // 損壞屏障
                    breakBarrier();
                    // 拋出異常
                    throw new TimeoutException();
                }
            }
        } finally {
            // 釋放鎖
            lock.unlock();
        }
    }

(2)核心流程

(3)nextGeneration方法

該方法會(huì)喚醒所有線程并且重置次數(shù),這也是為什么CyclicBarrier可以循環(huán)調(diào)用的原因

private void nextGeneration() {
        // signal completion of last generation
        // 喚醒所有線程
        trip.signalAll();
        // set up next generation
        // 恢復(fù)正在等待進(jìn)入屏障的線程數(shù)量
        count = parties;
        // 新生一代
        generation = new Generation();
    }

六、應(yīng)用

 
    static class MyThread extends Thread {
        private CyclicBarrier cb;
        public MyThread(String name, CyclicBarrier cb) {
            super(name);
            this.cb = cb;
        }
        public void run() {
            System.out.println(Thread.currentThread().getName() + " going to await");
            try {
                cb.await();
                System.out.println(Thread.currentThread().getName() + " continue");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        CyclicBarrier cb = new CyclicBarrier(3, new Thread("barrierAction") {
            public void run() {
                System.out.println(Thread.currentThread().getName() + " barrier action");
            }
        });
        MyThread t1 = new MyThread("t1", cb);
        MyThread t2 = new MyThread("t2", cb);
        t1.start();
        t2.start();
        System.out.println(Thread.currentThread().getName() + " going to await");
        cb.await();
        System.out.println(Thread.currentThread().getName() + " continue");
    }

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

所以調(diào)用時(shí)序?yàn)椋?/p>

到此這篇關(guān)于Java并發(fā)編程中的CyclicBarrier線程屏障詳解的文章就介紹到這了,更多相關(guān)CyclicBarrier線程屏障內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 多線程學(xué)習(xí)詳細(xì)總結(jié)

    Java 多線程學(xué)習(xí)詳細(xì)總結(jié)

    本文主要介紹 Java 多線程的知識(shí)資料,這里整理了詳細(xì)的多線程內(nèi)容,及簡(jiǎn)單實(shí)現(xiàn)代碼,有需要的朋友可以參考下
    2016-09-09
  • mybatis generator 使用方法教程(生成帶注釋的實(shí)體類)

    mybatis generator 使用方法教程(生成帶注釋的實(shí)體類)

    下面小編就為大家?guī)?lái)一篇mybatis generator 使用方法教程(生成帶注釋的實(shí)體類)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • Java遍歷Map對(duì)象的四種方式

    Java遍歷Map對(duì)象的四種方式

    本文給大家介紹java遍歷map對(duì)象的四種方式,對(duì)java中遍歷map感興趣的朋友可以一起了解了解
    2015-10-10
  • SpringBoot縮小打包體積的詳細(xì)步驟

    SpringBoot縮小打包體積的詳細(xì)步驟

    縮小打包體積是指通過(guò)各種優(yōu)化手段,減少Spring Boot應(yīng)用最終部署包(通常是JAR文件)的大小,這在微服務(wù)架構(gòu) 和云原生部署場(chǎng)景中尤為重要,因此本文給大家介紹了SpringBoot縮小打包體積的詳細(xì)步驟,需要的朋友可以參考下
    2026-03-03
  • 在Linux環(huán)境下搭建Java環(huán)境和部署Web項(xiàng)目

    在Linux環(huán)境下搭建Java環(huán)境和部署Web項(xiàng)目

    本文介紹了在Linux環(huán)境下搭建Java部署環(huán)境的步驟,包括使用虛擬機(jī)、WSL、云服務(wù)器等方法,重點(diǎn)講解了使用云服務(wù)器(如阿里云)的詳細(xì)步驟,包括購(gòu)買服務(wù)器、連接服務(wù)器、配置遠(yuǎn)程登錄、安裝必要的軟件包(如JDK和MySQL)以及部署Web項(xiàng)目
    2026-03-03
  • springboot2.6.4集成swagger3.0遇到的坑及解決方法

    springboot2.6.4集成swagger3.0遇到的坑及解決方法

    這篇文章主要介紹了springboot2.6.4如何集成swagger3.0,在集成的過(guò)程中遇到很多問(wèn)題,本文給大家分享四種問(wèn)題及相應(yīng)的解決方案,需要的朋友可以參考下
    2022-03-03
  • Java中泛型使用的簡(jiǎn)單方法介紹

    Java中泛型使用的簡(jiǎn)單方法介紹

    這篇文章主要給大家介紹了關(guān)于Java中泛型使用的簡(jiǎn)單方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Spring6整合JUnit的詳細(xì)步驟

    Spring6整合JUnit的詳細(xì)步驟

    這篇文章主要介紹了Spring6整合JUnit的詳細(xì)步驟,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • 詳解hashCode()和equals()的本質(zhì)區(qū)別和聯(lián)系

    詳解hashCode()和equals()的本質(zhì)區(qū)別和聯(lián)系

    這篇文章主要介紹了詳解hashCode()和equals()的本質(zhì)區(qū)別和聯(lián)系,本文先對(duì)兩種方法作了介紹,然后對(duì)二者聯(lián)系進(jìn)行分析,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • Java如何處理json字符串value多余雙引號(hào)

    Java如何處理json字符串value多余雙引號(hào)

    這篇文章主要介紹了Java如何處理json字符串value多余雙引號(hào),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03

最新評(píng)論

江永县| 台湾省| 宁乡县| 永城市| 西丰县| 桂林市| 泾阳县| 扎兰屯市| 八宿县| 荥经县| 兴安盟| 青阳县| 雷州市| 太保市| 绥阳县| 个旧市| 平山县| 临西县| 任丘市| 囊谦县| 成安县| 子长县| 张北县| 家居| 山阳县| 包头市| 原平市| 商都县| 曲周县| 留坝县| 武城县| 汾阳市| 工布江达县| 宜昌市| 广汉市| 枞阳县| 阿克陶县| 商南县| 武穴市| 淮北市| 镇原县|