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

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

【Java并發編程實戰】-----“J.U.C”:CyclicBarrier

2019-11-14 15:11:39
字體:
來源:轉載
供稿:網友

在上篇博客(【java并發編程實戰】-----“J.U.C”:Semaphore)中,LZ介紹了Semaphore,下面LZ介紹CyclicBarrier。在JDK API中是這么介紹的:

一個同步輔助類,它允許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。在涉及一組固定大小的線程的程序中,這些線程必須不時地互相等待,此時 CyclicBarrier 很有用。因為該 barrier 在釋放等待線程后可以重用,所以稱它為循環 的 barrier。

CyclicBarrier 支持一個可選的 Runnable 命令,在一組線程中的最后一個線程到達之后(但在釋放所有線程之前),該命令只在每個屏障點運行一次。若在繼續所有參與線程之前更新共享狀態,此屏障操作 很有用。

對于失敗的同步嘗試,CyclicBarrier 使用了一種要么全部要么全不 (all-or-none) 的破壞模式:如果因為中斷、失敗或者超時等原因,導致線程過早地離開了屏障點,那么在該屏障點等待的其他所有線程也將通過 BrokenBarrierException(如果它們幾乎同時被中斷,則用 InterruptedException)以反常的方式離開。

CyclicBarrier分析

CyclicBarrier結構如下:

2015090500001

 

從上圖可以看到CyclicBarrier內部使用ReentrantLock獨占鎖實現的。其構造函數如下:

CyclicBarrier(int parties):創建一個新的 CyclicBarrier,它將在給定數量的參與者(線程)處于等待狀態時啟動,但它不會在啟動 barrier 時執行預定義的操作。

CyclicBarrier(int parties, Runnable barrierAction):創建一個新的 CyclicBarrier,它將在給定數量的參與者(線程)處于等待狀態時啟動,并在啟動 barrier 時執行給定的屏障操作,該操作由最后一個進入 barrier 的線程執行。

public CyclicBarrier(int parties) {        this(parties, null);    }        public CyclicBarrier(int parties, Runnable barrierAction) {        if (parties <= 0) throw new IllegalArgumentException();        this.parties = parties;        this.count = parties;        this.barrierCommand = barrierAction;    }

在CyclicBarrier中,最重要的方法就是await(),在所有參與者都已經在此 barrier 上調用 await 方法之前,將一直等待。其源代碼如下:

public int await() throws InterruptedException, BrokenBarrierException {        try {            return dowait(false, 0L);        } catch (TimeoutException toe) {            throw new Error(toe); // cannot happen;        }    }

await內部調用dowait():

PRivate int dowait(boolean timed, long nanos)            throws InterruptedException, BrokenBarrierException,                   TimeoutException {            //獨占鎖            final ReentrantLock lock = this.lock;            //獲取獨占鎖            lock.lock();            try {                //保存當前"Generation"                final Generation g = generation;                //當前generation“已損壞”,拋出BrokenBarrierException異常                //拋出該異常一般都是某個線程在等待某個處于“斷開”狀態的CyclicBarrier                if (g.broken)                    throw new BrokenBarrierException();                //當前線程中斷,通過breakBarrier終止終止CyclicBarrier                if (Thread.interrupted()) {                    breakBarrier();                    throw new InterruptedException();                }                              //計數器-1               int index = --count;               //如果計數器 == 0               //表示所有線程都已經到位,觸發動作(是否執行某項任務)               if (index == 0) {  // tripped                   boolean ranAction = false;                   try {                       //barrierCommand線程要執行的任務                       final Runnable command = barrierCommand;                       //執行的任務!=null,執行任務                       if (command != null)                           command.run();                       ranAction = true;                       //喚醒所有等待線程,并更新generation。                       nextGeneration();                       return 0;                   } finally {                       if (!ranAction)                           breakBarrier();                   }               }               //循環一直執行,直到下面三個if一個條件滿足才會退出循環               for (;;) {                    try {                        //如果不是超時等待,則調用await等待                        if (!timed)                            trip.await();                        //調用awaitNanos等待                        else if (nanos > 0L)                            nanos = trip.awaitNanos(nanos);                    } catch (InterruptedException ie) {                        //                        if (g == generation && ! g.broken) {                            breakBarrier();                            throw ie;                        } else {                            Thread.currentThread().interrupt();                        }                    }                    //當前generation“已損壞”,拋出BrokenBarrierException異常                    //拋出該異常一般都是某個線程在等待某個處于“斷開”狀態的CyclicBarrier                    if (g.broken)                        throw new BrokenBarrierException();                    //generation已經更新,返回index                    if (g != generation)                        return index;                    //“超時等待”,并且時間已到,則通過breakBarrier()終止CyclicBarrier                    if (timed && nanos <= 0L) {                        breakBarrier();                        throw new TimeoutException();                    }                }            } finally {                //釋放獨占鎖                lock.unlock();            }        }

在dowait方法中其實處理邏輯還是比較簡單的:

1、首先判斷該barrier是否已經斷開了,如果斷開則拋出BrokenBarrierException異常;

2、判斷計算器index是否等于0,如果等于0,則表示所有的線程準備就緒,已經到達某個公共屏障點了,barrier可以進行后續工作了(是否執行某項任務(構造函數決定));然后調用nextGeneration方法進行更新換代工作(其中會喚醒所有等待的線程);

3、通過for循環(for(;;))使線程一直處于等待狀態。直到“有parties個線程到達barrier” 或 “當前線程被中斷” 或 “超時”這3者之一發生。

在dowait中有Generation這樣一個對象。該對象是CyclicBarrier的一個成員變量:

private static class Generation {        boolean broken = false;    }

Generation描述著CyclicBarrier的更顯換代。在CyclicBarrier中,同一批線程屬于同一代。當有parties個線程到達barrier,generation就會被更新換代。其中broken標識該當前CyclicBarrier是否已經處于中斷狀態。

對于中斷,CyclicBarrier是通過breakBarrier()實現的:

private void breakBarrier() {        generation.broken = true;        count = parties;        trip.signalAll();    }

在breakBarrier()中除了將broken設置為true,還會調用signalAll將在CyclicBarrier處于等待狀態的線程全部喚醒。

在超時的判斷中,CyclicBarrier根據timed的值來執行不同的wait。await、awaitNanos都是Condition中的方法。

當index = --count等于0時,標識“有parties個線程到達barrier”,臨界條件到達,則執行相應的動作。執行完動作后,則調用nextGeneration進行更新換代:

private void nextGeneration() {        //喚醒所有處于等待狀態的線程        trip.signalAll();        //初始化計數器        count = parties;        //產生新的Generation對象        generation = new Generation();    }

示例

1、線程等待到一定條件后才會繼續進行。

public class CyclicBarrierTest_1 {    private static CyclicBarrier barrier;        static class threadTest1 extends Thread{        public void run() {            System.out.println(Thread.currentThread().getName() + "達到...");            try {                barrier.await();            } catch (Exception e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread().getName() + "執行完成...");        }    }        public static void main(String[] args) {        barrier = new CyclicBarrier(5);        for(int i = 1 ; i <= 5 ; i++){            new threadTest1().start();        }    }}

------執行結果:

Thread-0達到...Thread-1達到...Thread-3達到...Thread-2達到...Thread-4達到...Thread-4執行完成...Thread-0執行完成...Thread-1執行完成...Thread-2執行完成...Thread-3執行完成...

2、線程等待到一定條件后,執行某項任務。比如說我們等車,只有當車坐滿后,汽車才會發動。

這個只需要對上面的代碼進行小動作的改動即可:

public class CyclicBarrierTest_2 {    private static CyclicBarrier barrier;        static class threadTest1 extends Thread{        public void run() {            System.out.println(Thread.currentThread().getName() + "達到...");            try {                barrier.await();            } catch (Exception e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread().getName() + "執行完成...");        }    }        public static void main(String[] args) {        barrier = new CyclicBarrier(5,new Runnable() {                        @Override            public void run() {                System.out.println("執行CyclicBarrier中的任務.....");            }        });        for(int i = 1 ; i <= 5 ; i++){            new threadTest1().start();        }    }}

-------執行結果:

Thread-0達到...Thread-1達到...Thread-3達到...Thread-4達到...Thread-2達到...執行CyclicBarrier中的任務.....Thread-2執行完成...Thread-0執行完成...Thread-3執行完成...Thread-1執行完成...Thread-4執行完成...

 

參考文獻:

1、Java多線程系列--“JUC鎖”10之 CyclicBarrier原理和示例


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
y97精品国产97久久久久久| 日韩av网站电影| 亚洲欧美激情在线视频| 久久99热这里只有精品国产| 亚洲欧美综合区自拍另类| 欧美成年人视频| 亚洲**2019国产| 成人乱人伦精品视频在线观看| 青青久久aⅴ北条麻妃| 久久精品视频免费播放| 亚洲欧美在线免费观看| 亚洲视频在线观看网站| 色偷偷88888欧美精品久久久| 久久伊人精品一区二区三区| 久久久久国产一区二区三区| 日韩不卡在线观看| 亚洲精品在线观看www| 欧美韩国理论所午夜片917电影| 中文字幕av一区中文字幕天堂| 欧美成人在线免费| 欧美国产日韩一区二区三区| 国内精品久久久久久中文字幕| 亚洲精品乱码久久久久久按摩观| 色香阁99久久精品久久久| 日韩电影中文字幕在线观看| 欧美专区中文字幕| 国产精品久久一区主播| 欧美精品videos另类日本| 国产精品免费观看在线| 日韩中文字幕在线播放| 欧美最猛性xxxxx免费| 国产精品极品尤物在线观看| 国产在线观看一区二区三区| 亚洲区一区二区| 久久久久中文字幕2018| 97国产真实伦对白精彩视频8| 国产欧美精品日韩| 亚洲欧洲xxxx| 欧美精品激情在线观看| 亚洲人免费视频| 日韩免费在线播放| 日韩精品免费在线| 精品视频在线观看日韩| 日本精品va在线观看| 国产欧美日韩中文| 国产成人一区二区在线| 欧美国产日韩中文字幕在线| 欧美亚洲国产日韩2020| 亚洲影视九九影院在线观看| 欧美老妇交乱视频| 久久久久久这里只有精品| 操人视频在线观看欧美| x99av成人免费| 国产日韩精品视频| 日韩av免费在线观看| 久久精品一区中文字幕| 亚洲成人久久网| 欧美精品videosex牲欧美| 亚洲一区二区三区xxx视频| 欧美成人精品影院| 成人国产精品免费视频| 午夜精品久久久久久久男人的天堂| 国产欧美在线观看| 91成品人片a无限观看| 欧美激情视频网站| 不卡中文字幕av| 欧美黑人一区二区三区| 92国产精品久久久久首页| 久久久久中文字幕| 粉嫩老牛aⅴ一区二区三区| 欧美夜福利tv在线| 日韩人在线观看| 久久久女女女女999久久| 欧美裸体xxxxx| 91在线观看欧美日韩| 日韩电视剧免费观看网站| 亚洲视频在线视频| 亚洲福利视频二区| 亚洲综合中文字幕在线| 在线视频欧美日韩精品| 一个人看的www久久| 亚洲成年人在线播放| 欧美大全免费观看电视剧大泉洋| 色狠狠久久aa北条麻妃| 日韩av在线直播| 在线视频欧美日韩| 久久久久久久激情视频| 狠狠躁18三区二区一区| 欧美性受xxxx白人性爽| 国产精品亚洲综合天堂夜夜| 亚洲精品美女在线| 97成人精品视频在线观看| 久久伊人精品一区二区三区| 国产综合在线观看视频| 欧美日韩亚洲天堂| 精品亚洲男同gayvideo网站| 日韩成人小视频| 欧美国产第二页| 国产精品专区h在线观看| 亚洲精品福利视频| 国产精品美女呻吟| 国产精品99久久久久久久久久久久| 国产精品第七十二页| 中文字幕精品av| 日韩少妇与小伙激情| 国内精品国产三级国产在线专| 日本精品性网站在线观看| 久久人人爽人人爽人人片av高清| 欧美理论在线观看| 久久精品国产清自在天天线| 欧洲永久精品大片ww免费漫画| 欧美大片大片在线播放| 亚洲欧美日韩精品久久亚洲区| 国产女精品视频网站免费| 91久久综合亚洲鲁鲁五月天| 亚洲乱码av中文一区二区| 亚洲女成人图区| 国产色综合天天综合网| 中国日韩欧美久久久久久久久| 性日韩欧美在线视频| 日韩免费在线免费观看| 亚洲人午夜精品| 亚洲午夜未满十八勿入免费观看全集| 国产成+人+综合+亚洲欧洲| 国产亚洲精品美女久久久久| 亚洲精品99久久久久中文字幕| 97福利一区二区| 欧美成人午夜剧场免费观看| 欧美大片在线影院| 欧美成人精品在线视频| 久久999免费视频| 欧美国产日韩视频| 国产精品v片在线观看不卡| 日韩在线视频二区| 日本久久91av| 午夜精品久久久久久久白皮肤| 亚洲乱亚洲乱妇无码| 国产精品一区=区| 欧美国产日韩免费| 日本免费久久高清视频| 91精品国产乱码久久久久久久久| 亚洲激情在线观看视频免费| 国产视频精品在线| 欧美一区第一页| 欧洲成人在线视频| 国产精品成人免费视频| 国内久久久精品| 欧美性猛交xxxxx免费看| 92看片淫黄大片欧美看国产片| 欧美丝袜一区二区| 精品一区电影国产| 亚洲国产精品久久久久| 亚洲精品一区二区久| 久久久欧美精品| 亚洲视频999| 亚洲国产精品系列| 亚洲影院在线看| 国产精品网红福利| 播播国产欧美激情| 亚洲第一区中文99精品| 一个色综合导航| 欧美成人小视频| 亚洲精品99久久久久中文字幕| 国产午夜一区二区|