Java並發編程--CyclicBarrier

來源:互聯網
上載者:User

標籤:

       CyclicBarrier 是一個同步輔助類,它允許一組線程互相等待,直到到達某個公用屏障點 (common barrier point)。在涉及一組固定大小的線程的程式中,這些線程必須不時地互相等待,此時 CyclicBarrier 很有用。因為該 barrier 在釋放等待線程後可以重用,所以稱它為迴圈 的 barrier。CyclicBarrier支援一個可選的 Runnable 命令,在一組線程中的最後一個線程到達之後(但在釋放所有線程之前),該命令只在每個屏障點運行一次。若在繼續所有參與線程之前更新共用狀態,此屏障操作 很有用。

 

業務需求

      一個大型任務常常分配好多子任務去執行,只有當所有的子任務都執行完成時,才能執行主任務。比如在考試系統的抽題邏輯中,抽題是一個大型任務,包括抽出各種題型,比如:單選題、多選題、翻譯題、聽力題。抽完所有的題才能繼續向下執行。按照咱們以前寫代碼的方式:先抽取單選題,再抽多選題,再抽翻譯題,再抽聽力題,假設每個抽題時間都為1s,那麼完成一個抽題需要4s的時間,顯然對電腦資源的利用率沒有達到最優。那麼我們如何提高效能呢?假設我們是4核的cpu,我們在抽單選題的時候可以同時抽多選題、翻譯題和聽力題,這樣相當於是並存執行多個任務,那麼抽完題需要的時間才是1s。

 

實現

      有了上面的需求,那麼下面我們來實現,如何抽題。

抽單選題類:

/** * 單選 *  * @author 康立賢 * *         2015年5月19日2015 */public class SingleSelect implements Runnable {private Resutl result;private  CyclicBarrier barrier;private int number;public SingleSelect(Resutl result,CyclicBarrier barrier,int number) {this.result = result;this.barrier=barrier;this.number=number;}public SingleSelect(Resutl result,int number){this.result = result;this.number=number;}@Overridepublic void run() {//System.out.println("單選==第"+number+"次==抽題===開始。。。");result.setSingleSelect("單選題。。。"+number);try {// 睡5s//Thread.sleep((int) (Math.random() * 1000));System.out.println("單選==第"+number+"次==抽題===結束。。。");barrier.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (BrokenBarrierException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void singleExam(){//System.out.println("單選==第"+number+"次==抽題===開始。。。");result.setSingleSelect("單選題。。。"+number);System.out.println("單選==第"+number+"次==抽題===結束。。。");}}

抽多選、翻譯、聽力的類與上面的類似,在此省略。

存放抽題結果的類---Result.java

/** * 存放抽取到的試題 * @author 康立賢 * * 2015年5月19日2015 */public class Resutl {private String singleSelect;private String doubleSelect;private String translate;private String listening;public String getSingleSelect() {return singleSelect;}public void setSingleSelect(String singleSelect) {this.singleSelect = singleSelect;}public String getDoubleSelect() {return doubleSelect;}public void setDoubleSelect(String doubleSelect) {this.doubleSelect = doubleSelect;}public String getTranslate() {return translate;}public void setTranslate(String translate) {this.translate = translate;}public String getListening() {return listening;}public void setListening(String listening) {this.listening = listening;}}

合并抽題結果類:---Combine.java

public class Combine implements Runnable{private Resutl result;public Combine(Resutl result){this.result=result;}@Overridepublic synchronized  void  run() {//synchronized(this){System.out.println("所有抽題全部完畢");System.out.println(result.getDoubleSelect());System.out.println(result.getSingleSelect());System.out.println(result.getTranslate());System.out.println(result.getListening());}}

用戶端:

public class Exam3Pool {//目前效能比較好的方式public static void main(String[] args) {// 擷取伺服器的cpu個數int cpuNum = Runtime.getRuntime().availableProcessors();System.out.println("cpu的個數是:" + cpuNum);// 合適的線程數量是cpu數量ExecutorService pool = Executors.newFixedThreadPool(cpuNum);for(int i=0;i<200000;i++){Resutl result=new Resutl();Combine combine=new Combine(result);CyclicBarrier barrier=new CyclicBarrier(4,combine);DoubleSelect doubleSelect=new DoubleSelect(result,barrier,i);Linstening listening=new Linstening(result,barrier,i);SingleSelect singleSelect=new SingleSelect(result,barrier,i);Translate translate=new Translate(result,barrier,i);//多選抽題Thread thDouble=new Thread(doubleSelect);//聽力抽題Thread thListen=new Thread(listening);//單選抽題Thread thSingle=new Thread(singleSelect);//翻譯抽題Thread thTranslate=new Thread(translate);pool.execute(thDouble);pool.execute(thListen);pool.execute(thSingle);pool.execute(thTranslate);}pool.shutdown();System.out.println("主線程結束.........");//20s//21個線程}}

總結:

      通過設定公用屏障點的方式,我們可以使線程同步,同步完成後執行下面的功能,比如說執行完一個任務需要5個子任務,使用此種方式是只要有一個子任務沒有完成,那麼其餘任務線程必須等待,不能再執行。我們考慮一下,如果一個子任務用的時間很長,那麼整個任務執行完畢的時間取決於執行最長時間的子任務,其他子任務線程完全等待,這樣資源並沒有得到很好的利用,那麼能不能在等待其他子任務完成之前讓完成了任務的子線程去執行其他任務呢?這樣可以使資源更充分的被利用?答案肯定是有的,下篇部落格我們會解決這個問題,敬請期待~~~


Java並發編程--CyclicBarrier

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.