日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Java并發編程:深入剖析CyclicBarrier源碼

來源: 責編: 時間:2024-04-29 16:16:45 244觀看
導讀引言CyclicBarrier中文叫做循環柵欄,用來控制線程的執行速率。適用場景:一組線程在到達柵欄之前,需要相互等待,到達柵欄之后(滿足了特定條件),再一起執行。適用場景好像跟CountDownLatch一樣,前面介紹過CountDownLatch的適用

引言

CyclicBarrier中文叫做循環柵欄,用來控制線程的執行速率。UoL28資訊網——每日最新資訊28at.com

適用場景:一組線程在到達柵欄之前,需要相互等待,到達柵欄之后(滿足了特定條件),再一起執行。UoL28資訊網——每日最新資訊28at.com

適用場景好像跟CountDownLatch一樣,前面介紹過CountDownLatch的適用場景,跟第二種場景很像,不過還是有點區別:UoL28資訊網——每日最新資訊28at.com

  1. CountDownLatch需要手動調用countDown()方法,這組線程才能一起執行,而CyclicBarrier無需調用調用任何方法,線程會自動執行。
  2. CountDownLatch只能使用一次,而CyclicBarrier可以循環使用。

再提一下CountDownLatch的兩個適用場景:UoL28資訊網——每日最新資訊28at.com

  1. 當前線程等待其他線程都執行完成之后,再執行。
  2. 所有線程滿足條件后,再一起執行。

使用示例

CyclicBarrier常用的方法就一個await()方法,調用await()方法之后,會阻塞當前線程,直到柵欄前的所有線程都調用了await()方法,才會放行,并且一起執行。UoL28資訊網——每日最新資訊28at.com

import lombok.extern.slf4j.Slf4j;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * @author 一燈架構 * @apiNote CyclicBarrier測試類 **/@Slf4jpublic class CyclicBarrierTest {    public static void main(String[] args) throws InterruptedException {        // 1. 創建一個線程池,用來執行任務        ExecutorService executorService = Executors.newCachedThreadPool();        // 2. 創建一個循環柵欄,線程數是3        CyclicBarrier cyclicBarrier = new CyclicBarrier(3);        // 3. 提交9個任務,剛好可以循環3輪        for (int i = 0; i < 9; i++) {            // 4. 睡眠100ms再提交任務,避免并發提交            Thread.sleep(100);            executorService.execute(() -> {                try {                    // 5. 睡眠1秒,模擬任務準備階段                    Thread.sleep(1000);                    log.info(Thread.currentThread().getName() + " 準備 " + cyclicBarrier.getNumberWaiting());                    // 6. 阻塞當前任務,直到3個線程都到達柵欄                    cyclicBarrier.await();                    log.info(Thread.currentThread().getName() + " 執行完成");                } catch (Exception e) {                }            });        }        // 7. 關閉線程池        executorService.shutdown();    }}

輸出結果:UoL28資訊網——每日最新資訊28at.com

10:00:00.001 [pool-1-thread-1] INFO com.yideng.CyclicBarrierTest - pool-1-thread-1 準備 010:00:00.002 [pool-1-thread-2] INFO com.yideng.CyclicBarrierTest - pool-1-thread-2 準備 110:00:00.003 [pool-1-thread-3] INFO com.yideng.CyclicBarrierTest - pool-1-thread-3 準備 210:00:00.003 [pool-1-thread-3] INFO com.yideng.CyclicBarrierTest - pool-1-thread-3 執行完成10:00:00.003 [pool-1-thread-1] INFO com.yideng.CyclicBarrierTest - pool-1-thread-1 執行完成10:00:00.004 [pool-1-thread-2] INFO com.yideng.CyclicBarrierTest - pool-1-thread-2 執行完成10:00:00.010 [pool-1-thread-4] INFO com.yideng.CyclicBarrierTest - pool-1-thread-4 準備 010:00:00.011 [pool-1-thread-5] INFO com.yideng.CyclicBarrierTest - pool-1-thread-5 準備 110:00:01.003 [pool-1-thread-6] INFO com.yideng.CyclicBarrierTest - pool-1-thread-6 準備 210:00:01.004 [pool-1-thread-6] INFO com.yideng.CyclicBarrierTest - pool-1-thread-6 執行完成10:00:01.004 [pool-1-thread-4] INFO com.yideng.CyclicBarrierTest - pool-1-thread-4 執行完成10:00:01.004 [pool-1-thread-5] INFO com.yideng.CyclicBarrierTest - pool-1-thread-5 執行完成10:00:01.114 [pool-1-thread-7] INFO com.yideng.CyclicBarrierTest - pool-1-thread-7 準備 010:00:01.213 [pool-1-thread-8] INFO com.yideng.CyclicBarrierTest - pool-1-thread-8 準備 110:00:01.317 [pool-1-thread-9] INFO com.yideng.CyclicBarrierTest - pool-1-thread-9 準備 210:00:01.318 [pool-1-thread-9] INFO com.yideng.CyclicBarrierTest - pool-1-thread-9 執行完成10:00:01.318 [pool-1-thread-7] INFO com.yideng.CyclicBarrierTest - pool-1-thread-7 執行完成10:00:01.319 [pool-1-thread-8] INFO com.yideng.CyclicBarrierTest - pool-1-thread-8 執行完成

示例中CyclicBarrier包含3個線程,提交9個任務,每3個任務為一組,調用await()方法后會相互等待,直到3個線程都調用了await()方法,然后放行,并且一起執行,9個任務會循環3輪,從輸出結果中可以看出。UoL28資訊網——每日最新資訊28at.com

示例中getNumberWaiting()方法可以查看CyclicBarrier中已經等待的線程數。UoL28資訊網——每日最新資訊28at.com

看完了CyclicBarrier的使用方式,再看一下CyclicBarrier的源碼實現。UoL28資訊網——每日最新資訊28at.com

類屬性

public class CyclicBarrier {    /**     * 互斥鎖,用來保證線程安全     */    private final ReentrantLock lock = new ReentrantLock();    /**     * 柵欄條件操作     */    private final Condition trip = lock.newCondition();        /**     * 柵欄初始線程數     */    private final int parties;        /**     * 到達柵欄后的操作     */    private final Runnable barrierCommand;    /**     * 柵欄前未到達的線程數     */    private int count;    /**     * 當前循環輪數     */    private Generation generation = new Generation();        private static class Generation {        boolean broken = false;    }}

CyclicBarrier內部使用了ReentrantLock來保證線程安全,又使用了Condition來實現線程的等待與喚醒操作。UoL28資訊網——每日最新資訊28at.com

初始化

CyclicBarrier初始化的可以指定線程數和到達柵欄后的操作。UoL28資訊網——每日最新資訊28at.com

/** * 指定線程數 */public CyclicBarrier(int parties) {    this(parties, null);}/** * 指定線程數和到達柵欄后的操作 * @param parties 線程數 * @param barrierAction 到達柵欄后的操作 */public CyclicBarrier(int parties, Runnable barrierAction) {    if (parties <= 0) {        throw new IllegalArgumentException();    }    this.parties = parties;    this.count = parties;    this.barrierCommand = barrierAction;}

比如到達柵欄后,關閉線程池:UoL28資訊網——每日最新資訊28at.com

CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> executorService.shutdown());

看一下await()方法源碼。UoL28資訊網——每日最新資訊28at.com

await方法源碼

/**     * await方法入口     */    public int await() throws InterruptedException, BrokenBarrierException {        try {            return dowait(false, 0L);        } catch (TimeoutException toe) {            throw new Error(toe); // cannot happen        }    }    /**     * await方法核心邏輯     * @param timed 是否允許超時,false表示不允許     * @param nanos 超時時間     */    private int dowait(boolean timed, long nanos)            throws InterruptedException, BrokenBarrierException, TimeoutException {        // 1. 加鎖        final ReentrantLock lock = this.lock;        lock.lock();        try {            // 2. 獲取當前循環輪數            final Generation g = generation;            if (g.broken) {                throw new BrokenBarrierException();            }            // 3. 如果當前線程已中斷,就打破柵欄            if (Thread.interrupted()) {                breakBarrier();                throw new InterruptedException();            }            // 4. 計數器減一,如果計數器為零,表示所有線程都到達了柵欄            int index = --count;            if (index == 0) {                boolean ranAction = false;                try {                    // 5. 如果初始化時指定了barrierCommand,就執行                    final Runnable command = barrierCommand;                    if (command != null) {                        command.run();                    }                    ranAction = true;                    nextGeneration();                    return 0;                } finally {                    if (!ranAction) {                        breakBarrier();                    }                }            }            for (; ; ) {                try {                    // 6. 如果不允許超時,就阻塞當前線程                    if (!timed) {                        trip.await();                    } else if (nanos > 0L) {                        nanos = trip.awaitNanos(nanos);                    }                } catch (InterruptedException ie) {                    if (g == generation && !g.broken) {                        breakBarrier();                        throw ie;                    } else {                        Thread.currentThread().interrupt();                    }                }                if (g.broken) {                    throw new BrokenBarrierException();                }                if (g != generation) {                    return index;                }                // 7. 如果已超時,就打破柵欄                if (timed && nanos <= 0L) {                    breakBarrier();                    throw new TimeoutException();                }            }        } finally {            // 8. 釋放鎖            lock.unlock();        }    }

await()方法源碼很長,但是邏輯很簡單,主要分為以下四步:UoL28資訊網——每日最新資訊28at.com

  1. 加鎖,保證線程安全。
  2. 統計柵欄前等待的線程數,如果所有線程都到達了柵欄,就執行初始化時指定的barrierCommand。
  3. 如果線程沒有指定了超時時間,就直接阻塞當前線程。如果指定了超時時間,就等待直到超時,如果已超時,就打破柵欄。
  4. 釋放鎖

再看一下打破柵欄的源碼:UoL28資訊網——每日最新資訊28at.com

/** * 打破柵欄 */private void breakBarrier() {    // 1. 設置當前循環輪數的狀態為已打破    generation.broken = true;    // 2. 重置線程數    count = parties;    // 3. 喚醒所有等待的線程    trip.signalAll();}

其他常用方法

CyclicBarrier還有一些常用的方法:UoL28資訊網——每日最新資訊28at.com

/** * 等待(帶超時時間) * @param timeout 超時時間 * @param unit 時間單位 */public int await(long timeout, TimeUnit unit)        throws InterruptedException,        BrokenBarrierException,        TimeoutException {    ...}/** * 重置柵欄(當柵欄出現異常情況時使用) */public void reset() {    ...}

總結

看完了CyclicBarrier的所有源碼,是不是覺得CyclicBarrier邏輯很簡單。UoL28資訊網——每日最新資訊28at.com

CyclicBarrier主要用來控制線程的執行速率,初始化時指定線程數,線程調用await()方法時會阻塞,直到到達的線程數等于初始線程數,才會放行,并且一起執行。與CountDownLatch區別是,CyclicBarrier可以循環執行,而CountDownLatch只能執行一次。UoL28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-86508-0.htmlJava并發編程:深入剖析CyclicBarrier源碼

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 請盡快升級你的 jQuery!

下一篇: Vue 超實用技巧!建立邏輯與動畫樣式的通道

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
亚洲午夜激情免费视频| 欧美视频一区二区| 久久不射中文字幕| 另类图片国产| 欧美日韩精品系列| 国产乱子伦一区二区三区国色天香 | 在线亚洲免费视频| 亚欧成人在线| 免费亚洲电影在线| 欧美另类视频| 国产欧美一区二区三区久久| 亚洲成人在线网| 一区二区日韩精品| 久久久www免费人成黑人精品| 欧美黑人多人双交| 国产毛片精品国产一区二区三区| 在线精品视频一区二区| 亚洲小说区图片区| 美女精品在线| 国产精品一区二区久久精品| 亚洲成在线观看| 亚洲综合二区| 欧美黑人国产人伦爽爽爽| 国产精品试看| 亚洲精品久久久久中文字幕欢迎你| 亚洲综合精品| 欧美喷水视频| 国产一区二区三区直播精品电影 | 国产一区二区毛片| 在线视频你懂得一区二区三区| 久久免费高清视频| 久久久天天操| av成人毛片| 久久综合九色综合欧美狠狠| 国产精品欧美一区喷水| 亚洲精品国产拍免费91在线| 欧美一区二区三区四区在线观看| 欧美精品国产精品| 在线视频观看日韩| 欧美在线精品免播放器视频| 欧美视频一区二区三区在线观看| 亚洲国产另类久久久精品极度| 欧美亚洲午夜视频在线观看| 欧美日韩一区在线观看| 精品福利免费观看| 午夜精品久久久久久久久久久 | 欧美三级电影一区| 亚洲国产人成综合网站| 久久国产精品久久久| 欧美三级午夜理伦三级中视频| 亚洲国内精品| 久久综合图片| 国产最新精品精品你懂的| 亚洲欧美一级二级三级| 欧美三级在线视频| 亚洲美女91| 欧美韩国日本一区| 亚洲激情精品| 免费在线成人| 在线观看三级视频欧美| 久久精品二区| 国产一区日韩欧美| 欧美在线播放视频| 国产日韩一区在线| 欧美一区二区日韩| 国产欧美精品一区二区色综合 | 国产精品午夜久久| 亚洲午夜av电影| 欧美日韩免费观看一区| 亚洲美女淫视频| 欧美精品一区三区| 亚洲精品综合| 欧美日韩成人综合| 日韩一级黄色av| 欧美日韩一二区| 在线午夜精品| 国产精品美女久久久浪潮软件| 亚洲一区二区三区影院| 国产精品久久久久久久久久久久 | 欧美精品一区二区精品网| 亚洲国产一区二区三区a毛片| 美女诱惑黄网站一区| 亚洲激情视频在线| 欧美理论片在线观看| 99精品视频一区| 欧美亚州在线观看| 亚洲欧美日韩综合| 国产亚洲精品久久久久婷婷瑜伽| 久久精品国产综合精品| 在线观看av不卡| 奶水喷射视频一区| 亚洲精品午夜精品| 欧美视频二区36p| 亚洲欧美精品中文字幕在线| 国产日韩一区欧美| 久久午夜激情| 亚洲精品欧美精品| 欧美午夜一区二区福利视频| 亚洲男女自偷自拍| 国产午夜精品一区理论片飘花| 午夜日韩在线| 国产欧美精品xxxx另类| 久久久久久久999| 亚洲国产日韩欧美| 欧美极品影院| 亚洲视频在线观看三级| 国产精品综合| 久久国产精品久久w女人spa| 狠狠色综合播放一区二区| 欧美a级一区| 中文日韩在线视频| 国产一区二区久久久| 欧美/亚洲一区| 制服诱惑一区二区| 国产一区二区三区在线观看精品| 蜜桃精品久久久久久久免费影院| 夜夜夜精品看看| 国产亚洲午夜高清国产拍精品| 蜜桃久久av一区| 亚洲午夜91| 伊人久久亚洲美女图片| 欧美精品18+| 亚洲综合首页| 亚洲福利视频免费观看| 国产精品成人免费视频| 久久琪琪电影院| 这里只有精品视频| 有坂深雪在线一区| 国产精品hd| 蜜臀91精品一区二区三区| 亚洲一区三区视频在线观看| 激情六月婷婷久久| 欧美性猛交一区二区三区精品| 久久精品国产成人| 99精品欧美一区二区三区综合在线 | 在线观看欧美日韩| 欧美日韩你懂的| 久久久精品国产免大香伊| 亚洲黄色一区| 国产欧美日韩一区二区三区在线观看 | 美女久久网站| 亚洲欧美日韩综合| 亚洲人成小说网站色在线| 国产精品外国| 免费观看一区| 亚洲欧美日韩国产一区二区三区| 国内一区二区三区| 在线视频日韩精品| 狠狠噜噜久久| 国产精品你懂的在线| 久久综合五月天婷婷伊人| 一区二区三区四区五区精品视频| 国产精品视频一二| 久久综合狠狠综合久久综合88 | 欧美成人蜜桃| 亚洲综合社区| 日韩视频永久免费| 国产主播一区二区三区| 欧美天堂亚洲电影院在线播放| 麻豆av福利av久久av| 亚洲欧美伊人| 一区二区欧美在线| 亚洲区第一页| 在线观看成人小视频| 国产精品久久久久99| 欧美精品一区二区三区蜜桃| 久久夜色精品亚洲噜噜国产mv | 久久成人这里只有精品| 亚洲综合成人在线| 99伊人成综合| 亚洲国内高清视频| 激情五月综合色婷婷一区二区| 国产精品美女久久久久久免费| 欧美刺激午夜性久久久久久久| 久久国产天堂福利天堂| 午夜精品美女久久久久av福利| 在线一区二区三区四区五区| 亚洲人成久久| 91久久久亚洲精品| 亚洲福利免费| 好吊视频一区二区三区四区| 国产精品一区二区久久精品| 国产精品草草| 欧美四级剧情无删版影片| 欧美日韩高清在线| 欧美精品在线极品| 欧美成人一区二区三区片免费| 久久偷看各类wc女厕嘘嘘偷窃| 久久国产黑丝| 久久成人免费日本黄色| 久久成人亚洲| 久久精品日韩欧美| 久久久福利视频| 久久精品欧洲| 久久噜噜噜精品国产亚洲综合| 久久久久久久久一区二区| 久久久久久久国产| 久久亚洲国产成人| 免费成人av在线看| 欧美高清不卡| 欧美日韩视频在线一区二区| 欧美视频不卡中文| 国产精品素人视频| 国产日韩在线亚洲字幕中文|