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

首頁 > 開發 > Java > 正文

Java并發實例之CyclicBarrier的使用

2024-07-13 10:14:02
字體:
來源:轉載
供稿:網友

最近一直整并發這塊東西,順便寫點Java并發的例子,給大家做個分享,也強化下自己記憶,如果有什么錯誤或者不當的地方,歡迎大家斧正。

CyclicBarrier是一種多線程并發控制實用工具,和CountDownLatch非常類似,它也可以實現線程間的計數等待,但是它的功能比CountDownLatch更加復雜且強大。

CyclicBarrier的介紹

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

CyclicBarrier默認的構造方法是CyclicBarrier(int parties),其參數表示屏障攔截的線程數量,每個線程調用await方法告訴CyclicBarrier我已經到達了屏障,然后當前線程被阻塞。

CyclicBarrier還提供一個更高級的構造函數CyclicBarrier(int parties, Runnable barrierAction),用于在線程到達屏障時,優先執行barrierAction這個Runnable對象,方便處理更復雜的業務場景。

java;">public CyclicBarrier(int parties) {  this(parties, null);}public int getParties() {  return parties;}

實現原理:在CyclicBarrier的內部定義了一個Lock對象,每當一個線程調用CyclicBarrier的await方法時,將剩余攔截的線程數減1,然后判斷剩余攔截數是否為0,如果不是,進入Lock對象的條件隊列等待。如果是,執行barrierAction對象的Runnable方法,然后將鎖的條件隊列中的所有線程放入鎖等待隊列中,這些線程會依次的獲取鎖、釋放鎖,接著先從await方法返回,再從CyclicBarrier的await方法中返回。

CyclicBarrier主要用于一組線程之間的相互等待,而CountDownLatch一般用于一組線程等待另一組些線程。實際上可以通過CountDownLatch的countDown()和await()來實現CyclicBarrier的功能。即 CountDownLatch中的countDown()+await() = CyclicBarrier中的await()。注意:在一個線程中先調用countDown(),然后調用await()。

構造函數CyclicBarrier可以理解為循環柵欄,這個計數器可以反復使用。比如,假設我們將計數器設置為10,那么湊齊第一批10個線程后,計數器就會歸零,然后接著湊齊下一批10個線程,這就是它的內在含義。

LOL和王者榮耀的玩家很多,許多人應該都有打大龍的經歷,話說前期大家打算一起去偷大龍,由于前期大家都比較弱,需要五個人都齊了才能打大龍,這樣程序該如何實現呢?本人很菜,開始我的代碼是這么寫的(哈哈大家不要糾結我的時間):

public class KillDragon {	/**   * 模擬打野去打大龍   */	public static void dayePlayDragon(){		System.out.println("打野在去打大龍的路上,需要10s");	}	/**   * 模擬上單去打大龍   */	public static void shangdanPlayDragon(){		System.out.println("上單在去打大龍的路上,需要10s");	}	/**   * 模擬中單去打大龍   */	public static void zhongdanPlayDragon(){		System.out.println("中單在去打大龍的路上,需要10s");	}	/**   * 模擬ADC和輔助去打大龍   */	public static void adcAndFuzhuPlayDragon(){		System.out.println("ADC和輔助在去打大龍的路上,需要10s");	}	/**   * 模擬大家一起去打大龍   */	public static void killDragon()	  {		System.out.println("打大龍...");	}	public static void main(String[] args)	  {		dayePlayDragon();		shangdanPlayDragon();		zhongdanPlayDragon();		adcAndFuzhuPlayDragon();		killDragon();	}

結果如下:

打野在去打大龍的路上,需要10s上單在去打大龍的路上,需要10s中單在去打大龍的路上,需要10sADC和輔助在去打大龍的路上,需要10s打大龍...

 這完了,大家在路上的時間就花了40s了,顯然是錯誤的。要是都這么干,對方把你塔都要偷光了。不行得改進下,怎么改呢,多線程并發執行,如是我改成了下面這樣的,用volatile關鍵字。

private static volatile int i = 4;  public static void main(String[] args) {    new Thread(new Runnable() {      @Override      public void run() {        long start = System.currentTimeMillis();        while (i!=0){        }        while (i==0) {          killDragon();          i--;          long t = System.currentTimeMillis() - start;          System.out.println("總共耗時:"+t+"毫秒");        }      }    }).start();    new Thread(new Runnable() {      @Override      public void run() {        dayePlayDragon();        try {          Thread.sleep(10000);          i--;        } catch (InterruptedException e) {          e.printStackTrace();        }      }    }).start();    new Thread(new Runnable() {      @Override      public void run() {        shangdanPlayDragon();        try {          Thread.sleep(10000);          i--;        } catch (InterruptedException e) {          e.printStackTrace();        }      }    }).start();    new Thread(new Runnable() {      @Override      public void run() {        zhongdanPlayDragon();        try {          Thread.sleep(10000);          i--;        } catch (InterruptedException e) {          e.printStackTrace();        }      }    }).start();    new Thread(new Runnable() {      @Override      public void run() {        adcAndFuzhuPlayDragon();        try {          Thread.sleep(10000);          i--;        } catch (InterruptedException e) {          e.printStackTrace();        }      }    }).start();  }

結果如下:

打野在去打大龍的路上,需要10s上單在去打大龍的路上,需要10s中單在去打大龍的路上,需要10sADC和輔助在去打大龍的路上,需要10s打大龍...總共耗時:10005毫秒

結果似乎還不錯,但是處理起來實在是有點麻煩,需要 while (i!=0)一直在那循環著。這時候學到了用 CyclicBarrier來處理,代碼如下:

public static void main(String[] args) {    CyclicBarrier barrier = new CyclicBarrier(5);    new Thread(new Runnable() {      @Override      public void run() {        long start = System.currentTimeMillis();        try {          barrier.await();        } catch (InterruptedException e) {          e.printStackTrace();        } catch (BrokenBarrierException e) {          e.printStackTrace();        }        killDragon();        long t = System.currentTimeMillis() - start;        System.out.println("總共耗時:"+t+"毫秒");      }    }).start();    new Thread(new Runnable() {      @Override      public void run() {        dayePlayDragon();        try {          Thread.sleep(10000);          barrier.await();        } catch (Exception e) {          e.printStackTrace();        }      }    }).start();    new Thread(new Runnable() {      @Override      public void run() {        shangdanPlayDragon();        try {          Thread.sleep(10000);          barrier.await();        } catch (Exception e) {          e.printStackTrace();        }      }    }).start();    new Thread(new Runnable() {      @Override      public void run() {        zhongdanPlayDragon();        try {          Thread.sleep(10000);          barrier.await();        } catch (Exception e) {          e.printStackTrace();        }      }    }).start();    new Thread(new Runnable() {      @Override      public void run() {        adcAndFuzhuPlayDragon();        try {          Thread.sleep(10000);          barrier.await();        } catch (Exception e) {          e.printStackTrace();        }      }    }).start();  }

大家都沒到達之前都等待,結果如下:

打野在去打大龍的路上,需要10s上單在去打大龍的路上,需要10s中單在去打大龍的路上,需要10sADC和輔助在去打大龍的路上,需要10s打大龍...總共耗時:10002毫秒

CyclicBarrier相當于線程的計數器:

CyclicBarrier初始化時規定一個數目,然后計算調用了CyclicBarrier.await()進入等待的線程數。當線程數達到了這個數目時,所有進入等待狀態的線程被喚醒并繼續。

CyclicBarrier就象它名字的意思一樣,可看成是個障礙, 所有的線程必須到齊后才能一起通過這個障礙。

CyclicBarrier初始時還可帶一個Runnable的參數, 此Runnable任務在CyclicBarrier的數目達到后,所有其它線程被喚醒前被執行。

當然這樣使用CyclicBarrier和使用CountDownLatch是沒什么區別的,正如前文所說的CyclicBarrier的功能更加的復雜且強大。給大家看一個《實戰Java高并發程序設計》一書上的一個例子。

比如:司令下達命令,要求10個士兵去一起完成一項任務。這時,就會要求10個士兵先集合報道,接著,一起雄赳赳氣昂昂地去執行任務。當10個士兵都執行完了任務,那么司機就可以對外宣稱,任務完成。相比CountDownLatch,CyclicBarrier可以接受一個參數作為BarrierAction。所謂的BarrierAction就是當計數器一次計數完成后,系統會執行的動作。如下構造函數,其中,parties表示技術總數,也就是參與的線程總數。

public CyclicBarrier(int parties, Runnable barrierAction)

下面示例演示了上述任務場景

public class CyclicBarrierDemo {  public static class Soldier implements Runnable {    private String soldier;    private final CyclicBarrier cyclicBarrier;    public Soldier(CyclicBarrier cyclicBarrier, String soldier) {      this.soldier = soldier;      this.cyclicBarrier = cyclicBarrier;    }    @Override    public void run() {      try {        cyclicBarrier.await();        doWork();        cyclicBarrier.await();      } catch (InterruptedException e) {        e.printStackTrace();      } catch (BrokenBarrierException e) {        e.printStackTrace();      }    }    void doWork() {      try {        Thread.sleep(Math.abs(new Random().nextInt() % 10000));      } catch (InterruptedException e) {        e.printStackTrace();      }      System.out.println(soldier + ":任務完成");    }  }  public static class BarrierRun implements Runnable {    boolean flag;    int N;    public BarrierRun(boolean flag, int N) {      this.flag = flag;      this.N = N;    }    @Override    public void run() {      if (flag) {        System.out.println("司令:[士兵" + N + "個,任務完成!");      } else {        System.out.println("司令:[士兵" + N + "個,集合完畢!");        flag = true;      }    }  }  public static void main(String args[]) {    final int N = 10;    Thread[] allSoldier = new Thread[N];    boolean flag = false;    CyclicBarrier cyclicBarrier = new CyclicBarrier(N, new BarrierRun(flag, N));    System.out.println("集合隊伍!");    for (int i = 0; i < N; i++) {      System.out.println("士兵" + i + "報道!");      allSoldier[i] = new Thread(new Soldier(cyclicBarrier, "士兵" + i));      allSoldier[i].start();    }  }}

執行結果如下:

集合隊伍!士兵0報道!士兵1報道!士兵2報道!士兵3報道!士兵4報道!士兵5報道!士兵6報道!士兵7報道!士兵8報道!士兵9報道!司令:[士兵10個,集合完畢!士兵0:任務完成士兵2:任務完成士兵9:任務完成士兵3:任務完成士兵7:任務完成士兵8:任務完成士兵1:任務完成士兵4:任務完成士兵5:任務完成士兵6:任務完成司令:[士兵10個,任務完成!

總結

以上就是本文關于Java并發實例之CyclicBarrier的使用的全部內容,希望對大家有所幫助。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久国产精彩视频| 欧美日韩在线视频首页| 美女av一区二区| 欧美三级免费观看| 久久艳片www.17c.com| 97视频免费在线观看| 欧美一级淫片播放口| 不卡中文字幕av| 国产97在线观看| 久久视频在线视频| 国产成人精品一区二区在线| 久久精品视频免费播放| 久久久亚洲国产天美传媒修理工| 日韩一级黄色av| 色香阁99久久精品久久久| 亚洲激情在线观看视频免费| 欧美激情中文网| 精品magnet| 国产精品三级久久久久久电影| 992tv在线成人免费观看| 国产成人在线视频| 欧美视频13p| 亚洲黄色片网站| 欧美电影免费观看大全| 欧美视频不卡中文| 亚洲色图激情小说| 97免费中文视频在线观看| 中文字幕日韩av电影| 91社区国产高清| 久久天天躁狠狠躁老女人| 国内精品模特av私拍在线观看| 亚洲最大中文字幕| 欧美在线视频网站| 成人精品一区二区三区电影免费| 欧美有码在线观看| 91视频国产一区| 操人视频在线观看欧美| 91精品在线影院| 国产精品都在这里| 精品久久久久久国产| 日韩福利视频在线观看| 国产九九精品视频| 亚洲精品小视频在线观看| 亚洲永久免费观看| 久久久亚洲成人| 欧美另类高清videos| 国产在线98福利播放视频| 国产一区二区三区免费视频| 亚洲va欧美va国产综合久久| 亚洲xxxxx电影| 欧美寡妇偷汉性猛交| 按摩亚洲人久久| 亚洲福利影片在线| 日韩激情av在线播放| 久久亚洲春色中文字幕| 精品在线欧美视频| 国产视频在线一区二区| 国产一区二区在线免费| 欧美日韩国产成人| 26uuu另类亚洲欧美日本一| 亚洲国产成人在线视频| 国产91精品久久久| 精品偷拍一区二区三区在线看| 欧美激情一区二区三区成人| 日韩电影免费观看在线| 亚洲国产精品久久91精品| 国产va免费精品高清在线| 疯狂欧美牲乱大交777| 成人免费淫片视频软件| 亚洲成人国产精品| 国产亚洲精品日韩| 精品视频—区二区三区免费| 91精品国产成人| 国产免费一区二区三区香蕉精| 国产日韩在线免费| 国产精品视频久久久| 成人中文字幕在线观看| 国产亚洲人成网站在线观看| 国产一区二区三区视频在线观看| 亚洲精品久久久久中文字幕欢迎你| 欧美最顶级丰满的aⅴ艳星| 成人激情视频在线观看| 亚洲成人a**站| 国产乱人伦真实精品视频| 视频在线观看一区二区| 黄色一区二区在线| 中国日韩欧美久久久久久久久| 国产精品视频网站| 亚洲网站在线播放| 欧美大片在线看免费观看| 久久久久久久久中文字幕| 日韩av在线免费观看| 中文字幕欧美日韩| 成人亲热视频网站| 最新中文字幕亚洲| 亚洲精品电影网在线观看| 亚洲成人在线视频播放| 高清一区二区三区日本久| …久久精品99久久香蕉国产| 亚洲成人久久网| 成人国产在线视频| www.美女亚洲精品| 亚洲一区二区在线播放| 在线播放日韩专区| 精品久久在线播放| 亚洲精品国产精品乱码不99按摩| 91中文在线观看| 国产亚洲精品久久久优势| 欧美激情网友自拍| 日韩国产精品视频| 日韩综合视频在线观看| 久久久精品在线| 91系列在线观看| 91久久中文字幕| 欧美成人剧情片在线观看| 热久久免费视频精品| 日韩欧美大尺度| 精品国产一区久久久| 亚洲中国色老太| 琪琪亚洲精品午夜在线| 91av在线播放视频| 欧美性xxxx极品hd满灌| 精品久久久久久久久久久| xvideos成人免费中文版| 91超碰caoporn97人人| 久久久久久69| 日韩精品高清在线观看| 国产精品久久久久久久久| 欧美一区二区三区免费观看| 欧美精品激情在线| 国产精品国产三级国产aⅴ浪潮| 欧美日韩性生活视频| 久久久之久亚州精品露出| 久久九九热免费视频| 亚洲成人av中文字幕| 青草成人免费视频| 日韩电影免费在线观看| 亚洲成人免费在线视频| 国产精品久久久久影院日本| 色综合视频一区中文字幕| 精品国产电影一区| 欧美午夜视频一区二区| 日韩三级影视基地| 欧美老少配视频| 久久精品成人一区二区三区| 国产精品久久久av| 日韩中文字幕不卡视频| 爱福利视频一区| 欧美性色xo影院| 亚洲人成网站777色婷婷| 国产小视频国产精品| 中文综合在线观看| 在线电影欧美日韩一区二区私密| 一区二区三区国产在线观看| 中文综合在线观看| 色综合久久久久久中文网| 91亚洲精品一区二区| 国产精品wwww| 欧美激情国产高清| 亚洲精品国产欧美| 日韩av色在线| 日韩精品视频在线观看网址| 亚洲精品一区二区三区婷婷月| 中文字幕av一区二区三区谷原希美|