少年阿賓

          那些青春的歲月

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks
          在多線程設(shè)計中,我猜常常會遇到線程間相互等待以及某個線程等待1個或多個線程的場景,比如多線程精密計算和大量數(shù)據(jù)處理,這里寫下我自己的體會和理解。

             

              我想應(yīng)該有很多辦法,如果是簡單的1:1關(guān)系,那么可以wait()和notify()解決,就像一把鎖和一把鑰匙;如果是1:N關(guān)系,這個1就需要關(guān)心N的所有狀態(tài)了,最笨的辦法是1可以去查看N當(dāng)前的狀態(tài),輪詢詢問工作是否做完。而好點的辦法是N做完后主動告訴1,然后N就會有2種選擇,要么聽從1的命令,要么繼續(xù)干自己其他的活。

           

              用傳統(tǒng)的方法我想應(yīng)該是都能實現(xiàn)的,而JDK1.5提供了CyclicBarrier與CountDownLatch來解決了這兩個問題,而她們的區(qū)別是:

              CyclicBarrier使所有線程相互等待,而CountDownLatch使一個或多個線程等待其他線程。區(qū)別類似上面藍色字體,CountDownLatch不會等待其他線程了,只要做完自己的工作就干自己的活去了,也就是run()方法里其他的任務(wù)。

           

          Example:

           

           

          public static void testCountDownLatch() throws InterruptedException{   
            CountDownLatch cdl
          =new CountDownLatch(2);   
            ExecutorService exe
          =Executors.newFixedThreadPool(2);   
             
          class Bow implements  Runnable{   
              CountDownLatch cdl;   
              
          public Bow(CountDownLatch cdl){   
              
          this.cdl=cdl;    
              }
             
              
          public void run(){   
               System.out.println(
          "The bow is coming");   
               System.out.println(
          "kick a bow ");   
               
          this.cdl.countDown();   
               System.out.println(
          "do other thing");   
               }
             
             }
             
            exe.execute(
          new Bow(cdl));   
            exe.execute(
          new Bow(cdl));   
            exe.shutdown();   
            System.out.println(
          "Wait");   
              cdl.await();   
              System.out.println(
          "End..");   
              
           }
             
            
              
          public static void main(String[] args) {   
                  
          try {   
                      Test.testCountDownLatch();   
                  }
           catch (InterruptedException e) {   
                  }
             
              }
            

           

          輸出的結(jié)果為:

           

          The bow is coming
          kick a bow
          do other thing
          Wait...
          The bow is coming
          kick a bow
          do other thing
          End..

           

          如上所說do other thing不受影響。

           

          寫了一個CyclicBarrier的例子:

           

          public static void testCyclicBarrier() throws InterruptedException, BrokenBarrierException{
                  CyclicBarrier barr
          =new CyclicBarrier(2+1);
                  
                  ExecutorService exe
          =Executors.newFixedThreadPool(2);
                   
          class Bow implements  Runnable{
                       CyclicBarrier barr;
                          
          public Bow(CyclicBarrier barr){
                          
          this.barr=barr;    
                          }

                          
          public void run(){
                              System.out.println(
          "The bow is coming");
                              System.out.println(
          "kick a down");
                              
          try {
                                  barr.await();
                              }
           catch (InterruptedException e) {
                                  
          // TODO Auto-generated catch block
                                  e.printStackTrace();
                              }
           catch (BrokenBarrierException e) {
                                  
          // TODO Auto-generated catch block
                                  e.printStackTrace();
                              }

                              System.out.println(
          "do other thing");
                              }

                      }

                  exe.execute(
          new Bow(barr));
                  exe.execute(
          new Bow(barr));
                  exe.shutdown();
                  System.out.println(
          "Wait");
                  barr.await();
                 System.out.println(
          "End..");
              
              }



              
          public static void main(String[] args) {
                  
          try {
                      Test.testCyclicBarrier();
                  }
           catch (InterruptedException e) {
                  }

                  
          catch (BrokenBarrierException e) {
                  }

              }

           

          輸出結(jié)果為:

           

          Wait...
          The bow is coming
          kick a down
          The bow is coming
          kick a down
          do other thing
          End..
          do other thing

           

          總結(jié):

          我們看到do other thing被阻塞了,直到最后才執(zhí)行,可見,柵欄和計數(shù)器的目完全不同了。向Doug Lea牛人學(xué)習(xí):)

           









          在網(wǎng)上看到很多人對于CountDownLatch和CyclicBarrier的區(qū)別簡單理解為CountDownLatch是一次性的,而CyclicBarrier在調(diào)用reset之后還可以繼續(xù)使用。那如果只是這么簡單的話,我覺得CyclicBarrier簡單命名為ResetableCountDownLatch好了,顯然不是的。
          我的理解是,要從他們的設(shè)計目的去看這兩個類。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里面要準(zhǔn)確理解他們的差異還是不容易的。
          我的理解是

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



          CountDownLatch 是計數(shù)器, 線程完成一個就記一個, 就像 報數(shù)一樣, 只不過是遞減的.
          而CyclicBarrier更像一個水閘, 線程執(zhí)行就想水流, 在水閘處都會堵住, 等到水滿(線程到齊)了, 才開始泄流.

          posted on 2013-04-28 15:37 abin 閱讀(457) 評論(0)  編輯  收藏 所屬分類: JavaMultithread
          主站蜘蛛池模板: 阜宁县| 霍林郭勒市| 西丰县| 苗栗县| 阿瓦提县| 陵水| 衡水市| 盈江县| 通道| 铁岭县| 静安区| 英德市| 拉孜县| 堆龙德庆县| 彰武县| 曲阳县| 横山县| 革吉县| 博白县| 红安县| 进贤县| 睢宁县| 长阳| 贵州省| 武平县| 甘孜| 鹤壁市| 商洛市| 乌兰察布市| 健康| 宝丰县| 丹凤县| 宁武县| 星子县| 宜州市| 红河县| 子洲县| 贡觉县| 九龙县| 昭通市| 临夏市|