亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

《java.util.concurrent 包源碼閱讀》21 CyclicBarrier和CountDownLatch

2019-11-14 21:03:17
字體:
來源:轉載
供稿:網友
java.util.concurrent 包源碼閱讀》21 CyclicBarrier和CountDownLatch

CyclicBarrier是一個用于線程同步的輔助類,它允許一組線程等待彼此,直到所有線程都到達集合點,然后執行某個設定的任務。

現實中有個很好的例子來形容:幾個人約定了某個地方集中,然后一起出發去旅行。每個參與的人就是一個線程,CyclicBarrier就是那個集合點,所有人到了之后,就一起出發。

CyclicBarrier的構造函數有兩個:

// parties是參與等待的線程的數量,barrierAction是所有線程達到集合點之后要做的動作public CyclicBarrier(int parties, Runnable barrierAction);// 達到集合點之后不執行操作的構造函數public CyclicBarrier(int parties)

需要說明的是,CyclicBarrier只是記錄線程的數目,CyclicBarrier是不創建任何線程的。線程是通過調用CyclicBarrier的await方法來等待其他線程,如果調用await方法的線程數目達到了預設值,也就是上面構造方法中的parties,CyclicBarrier就會開始執行barrierAction。

因此我們來看CyclicBarrier的核心方法dowait,也就是await方法調用的私有方法:

    PRivate int dowait(boolean timed, long nanos)        throws InterruptedException, BrokenBarrierException,               TimeoutException {        final ReentrantLock lock = this.lock;        lock.lock();        try {            final Generation g = generation;            if (g.broken)                throw new BrokenBarrierException();            if (Thread.interrupted()) {                breakBarrier();                throw new InterruptedException();            }           // count就是預設的parties,count減1的值表示還剩余幾個           // 線程沒有達到該集合點           int index = --count;           // index為0表示所有的線程都已經達到集合點,這時           // 占用最后一個線程,執行運行設定的任務           if (index == 0) {               boolean ranAction = false;               try {                   final Runnable command = barrierCommand;                   if (command != null)                       command.run();                   ranAction = true;                   // 喚醒其他等待的線程,                   // 更新generation以便下一次運行                   nextGeneration();                   return 0;               } finally {                   // 如果運行任務時發生異常,設置狀態為broken                   // 并且喚醒其他等待的線程                   if (!ranAction)                       breakBarrier();               }           }            // 還有線程沒有調用await,進入循環等待直到其他線程            // 達到集合點或者等待超時            for (;;) {                try {                    // 如果沒有設置超時,進行無超時的等待                    if (!timed)                        trip.await();                    // 有超時設置,進行有超時的等待                    else if (nanos > 0L)                        nanos = trip.awaitNanos(nanos);                } catch (InterruptedException ie) {                    // generation如果沒有被更新表示還是當前的運行                    // (generation被更新表示集合完畢并且任務成功),                    // 在狀態沒有被設置為broken狀態的情況下,遇到線程                    // 中斷異常表示當前線程等待失敗,需要設置為broken                    // 狀態,并且拋出中斷異常                    if (g == generation && ! g.broken) {                        breakBarrier();                        throw ie;                    } else {                        // else對應的條件為:g != generation || g.broken                        // 表示要么generation已經被更新意味著所有線程已經到達                        // 集合點并且任務執行成功,要么就是是broken狀態意味著                        // 任務執行失敗,無論哪種情況所有線程已經達到集合點,當                        // 前線程要結束等待了,發生了中斷異常,需要中斷當前線程                        // 表示遇到了中斷異常。                        Thread.currentThread().interrupt();                    }                }                // 如果發現當前狀態為broken,拋出異常                if (g.broken)                    throw new BrokenBarrierException();                // generation被更新表示所有線程都已經達到集合點                // 并且預設任務已經完成,返回該線程進入等待順序號                if (g != generation)                    return index;                // 等待超時,設置為broken狀態并且拋出超時異常                if (timed && nanos <= 0L) {                    breakBarrier();                    throw new TimeoutException();                }            }        } finally {            lock.unlock();        }    }

1. 任何一個線程等待時發生異常,CyclicBarrier都將被設置為broken狀態,運行都會失敗

2. 每次運行成功之后CyclicBarrier都會清理運行狀態,這樣CyclicBarrier可以重新使用

3. 對于設置了超時的等待,在發生超時的時候會引起CyclicBarrier的broken

說完了CyclicBarrier,再來說說CountDownLatch。

CountDownLatch同樣也是一個線程同步的輔助類,同樣適用上面的集合點的場景來解釋,但是運行模式完全不同。

CyclicBarrier是參與的所有的線程彼此等待,CountDownLatch則不同,CountDownLatch有一個導游線程在等待,每個線程報到一下即可無須等待,等到導游線程發現所有人都已經報到了,就結束了自己的等待。

CountDownLatch的構造方法允許指定參與的線程數量:

public CountDownLatch(int count)

參與線程使用countDown表示報到:

    public void countDown() {        sync.releaseShared(1);    }

看到releaseShared很容易使人聯想到共享鎖,那么試著用共享鎖的運行模式來解釋就簡單得多了:

和信號量的實現類似,CountDownLatch內置一下有限的共享鎖。

每個參與線程擁有一把共享鎖,調用countDown就等于是釋放了自己的共享鎖,導游線程await等于一下子要拿回所有的共享鎖。那么基于AbstractQueuedSynchronizer類來實現就很簡單了:

    public void await() throws InterruptedException {        sync.acquireSharedInterruptibly(1);    }    public boolean await(long timeout, TimeUnit unit)        throws InterruptedException {        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));    }

在await時注意到數量是1,其實這個參數對于CountDownLatch實現的Sync類(AbstractQueuedSynchronizer的子類)來說是不起作用的,因為需要保證await獲取共享鎖時必須拿到所有的共享鎖,這個參數也就變得沒有意義了??匆幌耂ync的tryAcquireShared方法就明白了:

        protected int tryAcquireShared(int acquires) {            // 和信號量Semaphore的實現一樣,使用state來存儲count,            // 每次釋放共享鎖就把state減1,state為0表示所有的共享            // 鎖已經被釋放。注意:這里的acquires參數不起作用            return (getState() == 0) ? 1 : -1;        }

因此Sync的tryReleaseShared就是更新state(每次state減1):

        protected boolean tryReleaseShared(int releases) {            // 每次state減1,當state為0,返回false表示所有的共享鎖都已經釋放            for (;;) {                int c = getState();                if (c == 0)                    return false;                int nextc = c-1;                if (compareAndSetState(c, nextc))                    return nextc == 0;            }        }

CyclicBarrier和CountDownLatch本質上來說都是多個線程同步的輔助工具,前者可以看成分布式的,后者可以看出是主從式。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久久久久久ktv| 国产精品视频免费在线| 国内偷自视频区视频综合| 91精品久久久久久久久久久久久久| 国a精品视频大全| 亚洲国产美女久久久久| 亚洲欧洲成视频免费观看| 国产女同一区二区| 亚洲aⅴ男人的天堂在线观看| 日韩精品福利在线| 国产精品69久久久久| 亚洲精品98久久久久久中文字幕| 亚洲性无码av在线| 91精品久久久久久久久久久久久久| 在线精品视频视频中文字幕| 一区二区三区天堂av| 91福利视频在线观看| 亚洲欧美日韩国产成人| 欧美一级高清免费| 国产视频亚洲精品| 播播国产欧美激情| 在线观看国产精品日韩av| 日韩精品视频观看| 国产欧美日韩丝袜精品一区| 国产视频丨精品|在线观看| 亚洲精品久久久久久久久久久| 久久久久国产精品免费| 国产va免费精品高清在线| 亚洲大尺度美女在线| 久久久精品美女| 欧美视频在线免费| 最新国产成人av网站网址麻豆| 久久影视电视剧免费网站| 亚洲国产精品成人va在线观看| 亚洲偷熟乱区亚洲香蕉av| 国产精品电影久久久久电影网| 欧美裸体xxxx极品少妇软件| 日韩高清a**址| 这里只有视频精品| 久久天天躁狠狠躁夜夜躁2014| 精品久久久久久久久久国产| 欧美午夜视频在线观看| 国产精品第二页| 欧美老少做受xxxx高潮| 91社区国产高清| 色噜噜狠狠色综合网图区| 欧美成人精品一区| 777777777亚洲妇女| 疯狂做受xxxx高潮欧美日本| 欧美大片在线看免费观看| 超碰日本道色综合久久综合| 日韩美女免费线视频| 亚洲欧美日韩一区二区在线| 91在线无精精品一区二区| 欧美激情欧美狂野欧美精品| 日韩精品电影网| 亚洲天堂免费观看| 亚洲电影免费观看高清完整版| 91国偷自产一区二区三区的观看方式| 色综合久久中文字幕综合网小说| 久久手机精品视频| 国产精品美腿一区在线看| 日韩av在线免费看| 这里只有精品久久| 国产精品视频色| 日韩欧美999| 92看片淫黄大片看国产片| 亚洲欧洲中文天堂| 国产日本欧美一区二区三区在线| 4444欧美成人kkkk| 欧日韩在线观看| 欧美激情网站在线观看| 国产精品日韩欧美大师| 69av成年福利视频| 精品日本美女福利在线观看| 久久久综合av| 中文字幕日韩av综合精品| 成人黄色片在线| 亚洲色图综合久久| 亚洲大胆美女视频| 中文字幕久久久av一区| 久久av在线看| 欧美夜福利tv在线| 日韩国产精品亚洲а∨天堂免| 亚洲精品日韩在线| 中文字幕精品在线视频| 午夜精品久久久久久久99黑人| 久久久久久久久久久av| 97婷婷大伊香蕉精品视频| 亚洲欧美日韩爽爽影院| 欧美性猛交xxxx免费看| 成人黄色在线播放| 久久人人爽人人爽人人片av高清| 亚洲日本成人女熟在线观看| 欧美又大粗又爽又黄大片视频| 午夜精品久久久久久久99黑人| 国产精品视频久久久久| 国产美女久久精品| 午夜精品三级视频福利| 一区二区在线视频播放| 欧美久久久精品| 啪一啪鲁一鲁2019在线视频| 亚洲人免费视频| www.久久草.com| 国产精品美女久久久免费| 国产在线精品自拍| 成人亚洲激情网| 国产成人精品视频在线观看| 自拍亚洲一区欧美另类| 136fldh精品导航福利| 91视频8mav| 伊人久久大香线蕉av一区二区| 国产99久久精品一区二区 夜夜躁日日躁| 亚洲xxxx3d| 91av在线网站| 日韩精品免费一线在线观看| 久久免费视频在线| 不卡中文字幕av| 国产v综合ⅴ日韩v欧美大片| 青青精品视频播放| 成人激情春色网| 欧美小视频在线观看| 亚洲乱码一区二区| 2019亚洲日韩新视频| 97在线视频一区| 国产欧美 在线欧美| 97国产精品视频| 欧美激情精品久久久久久大尺度| 久久精品国产99国产精品澳门| 亚洲电影中文字幕| 欧美精品日韩www.p站| 国产精品夜色7777狼人| 欧美激情视频在线| 亚洲已满18点击进入在线看片| 亚洲性夜色噜噜噜7777| 4k岛国日韩精品**专区| 国产精品激情av电影在线观看| 亚洲一区二区三区视频播放| 51精品国产黑色丝袜高跟鞋| 亚洲成人黄色网| 国产91ⅴ在线精品免费观看| 成人福利视频在线观看| 日韩日本欧美亚洲| 亚洲毛片一区二区| 亚洲精品720p| 欧美日韩精品中文字幕| 久久精品一偷一偷国产| 精品五月天久久| 91亚洲国产成人精品性色| 欧美国产日韩xxxxx| 欧美在线性视频| 国产日韩av在线播放| 日韩性生活视频| 色先锋资源久久综合5566| 国产精品91在线观看| 欧美丝袜第一区| 亚洲欧美在线免费| 超碰日本道色综合久久综合| 一本色道久久88综合亚洲精品ⅰ| 欧美噜噜久久久xxx| 亚洲成年网站在线观看| 欧美日韩在线观看视频小说| 久久久久久久国产精品视频| 精品国产精品三级精品av网址|