CountDownLatch和CyclicBarrier的區別

來源:互聯網
上載者:User

標籤:style   blog   color   io   使用   java   ar   strong   for   

在網上看到很多人對於CountDownLatch和CyclicBarrier的區別簡單理解為CountDownLatch是一次性的,而 CyclicBarrier在調用reset之後還可以繼續使用。那如果只是這麼簡單的話,我覺得CyclicBarrier簡單命名為ResetableCountDownLatch好了,顯然不是的。
我的理解是,要從他們的設計目的去看這兩個類。javadoc裡面的描述是這樣的。

 

CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

CyclicBarrier : A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.

 

可能是我的英語不夠好吧, 我感覺從這個javadoc裡面要準確理解他們的差異還是不容易的。
我的理解是

 

CountDownLatch : 一個線程(或者多個), 等待另外N個線程完成某個事情之後才能執行。  CyclicBarrier        : N個線程相互等待,任何一個線程完成之前,所有的線程都必須等待。
這樣應該就清楚一點了,對於CountDownLatch來說,重點是那個“一個線程”, 是它在等待, 而另外那N的線程在把“某個事情”做完之後可以繼續等待,可以終止。而對於CyclicBarrier來說,重點是那N個線程,他們之間任何一個沒有完成,所有的線程都必須等待。

 

 

 

CountDownLatch 是計數器, 線程完成一個就記一個, 就像 報數一樣, 只不過是遞減的.

 

而CyclicBarrier更像一個水閘, 線程執行就想水流, 在水閘處都會堵住, 等到水滿(線程到齊)了, 才開始泄流.

 

 

 

CyclicBarrier

 

假設有只有的一個情境:每個線程代表一個跑步運動員,當運動員都準備好後,才一起出發,只要有一個人沒有準備好,大家都等待.

 

    import java.io.IOException;      import java.util.Random;      import java.util.concurrent.BrokenBarrierException;      import java.util.concurrent.CyclicBarrier;      import java.util.concurrent.ExecutorService;      import java.util.concurrent.Executors;            class Runner implements Runnable {                private CyclicBarrier barrier;                private String name;                public Runner(CyclicBarrier barrier, String name) {              super();              this.barrier = barrier;              this.name = name;          }                @Override          public void run() {              try {                  Thread.sleep(1000 * (new Random()).nextInt(8));                  System.out.println(name + " 準備OK.");                  barrier.await();              } catch (InterruptedException e) {                  e.printStackTrace();              } catch (BrokenBarrierException e) {                  e.printStackTrace();              }              System.out.println(name + " Go!!");          }      }            public class Race {                public static void main(String[] args) throws IOException, InterruptedException {              CyclicBarrier barrier = new CyclicBarrier(3);                    ExecutorService executor = Executors.newFixedThreadPool(3);              executor.submit(new Thread(new Runner(barrier, "zhangsan")));              executor.submit(new Thread(new Runner(barrier, "lisi")));              executor.submit(new Thread(new Runner(barrier, "wangwu")));                    executor.shutdown();          }            }  

 

 

 

總結:CyclicBarrier就是一個柵欄,等待所有線程到達後再執行相關的操作。barrier 在釋放等待線程後可以重用。

 

 

 

CountDownLatch

 

    import java.util.concurrent.CountDownLatch;      /**      * 樣本:CountDownLatch的使用舉例      * Mail: [email protected]      * @author janeky      */      public class TestCountDownLatch {          private static final int N = 10;                public static void main(String[] args) throws InterruptedException {              CountDownLatch doneSignal = new CountDownLatch(N);              CountDownLatch startSignal = new CountDownLatch(1);//開始執行訊號                    for (int i = 1; i <= N; i++) {                  new Thread(new Worker(i, doneSignal, startSignal)).start();//線程啟動了              }              System.out.println("begin------------");              startSignal.countDown();//開始執行啦              doneSignal.await();//等待所有的線程執行完畢              System.out.println("Ok");                }                static class Worker implements Runnable {              private final CountDownLatch doneSignal;              private final CountDownLatch startSignal;              private int beginIndex;                    Worker(int beginIndex, CountDownLatch doneSignal,                      CountDownLatch startSignal) {                  this.startSignal = startSignal;                  this.beginIndex = beginIndex;                  this.doneSignal = doneSignal;              }                    public void run() {                  try {                      startSignal.await(); //等待開始執行訊號的發布                      beginIndex = (beginIndex - 1) * 10 + 1;                      for (int i = beginIndex; i <= beginIndex + 10; i++) {                          System.out.println(i);                      }                  } catch (InterruptedException e) {                      e.printStackTrace();                  } finally {                      doneSignal.countDown();                  }              }          }      }  

 

 


總結:CounDownLatch對於管理一組相關線程非常有用。上述範例程式碼中就形象地描述了兩種使用方式。第一種是計算機為1,代表了兩種狀態,開 關。第二種是計數器為N,代表等待N個操作完成。今後我們在編寫多線程程式時,可以使用這個構件來管理一組獨立線程的執行。

CountDownLatch和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.