神奇好望角 The Magical Cape of Good Hope

          庸人不必自擾,智者何需千慮?
          posts - 26, comments - 50, trackbacks - 0, articles - 11
            BlogJava :: 首頁(yè) ::  :: 聯(lián)系 :: 聚合  :: 管理

          非主流并發(fā)工具之 CyclicBarrier

          Posted on 2011-10-17 11:21 蜀山兆孨龘 閱讀(1794) 評(píng)論(0)  編輯  收藏 所屬分類: Java SE

          CyclicBarrier 的功能類似于前面說(shuō)到的 CountDownLatch,用于讓多個(gè)線程(子任務(wù))互相等待,直到共同到達(dá)公共屏障點(diǎn)(common barrier point),在這個(gè)點(diǎn)上,所有的子任務(wù)都已完成,從而主任務(wù)完成。

          該類構(gòu)造的時(shí)候除了必須要指定線程數(shù)量,還可以傳入一個(gè) Runnable 對(duì)象,它的 run 方法將在到達(dá)公共屏障點(diǎn)后執(zhí)行一次。子線程完成計(jì)算后,分別調(diào)用 CyclicBarrier#await 方法進(jìn)入阻塞狀態(tài),直到其他所有子線程都調(diào)用了 await

          下面仍然以運(yùn)動(dòng)員準(zhǔn)備賽跑為例來(lái)說(shuō)明 CyclicBarrier 的用法:

                      final int count = 8;
                      System.out.println("運(yùn)動(dòng)員開始就位。");
          
                      final CyclicBarrier cb = new CyclicBarrier(count, new Runnable() {
                          @Override
                          public void run() {
                              System.out.println("比賽開始...");
                          }
                      });
          
                      for (int i = 1; i <= count; i++) {
                          final int number = i;
                          new Thread() {
                              @Override
                              public void run() {
                                  System.out.println(number + " 號(hào)運(yùn)動(dòng)員到場(chǎng)并開始準(zhǔn)備...");
                                  try {
                                      // 準(zhǔn)備 2~5 秒鐘。
                                      TimeUnit.SECONDS.sleep(new Random().nextInt(4) + 2);
                                  } catch (InterruptedException ex) {
                                  }
                                  System.out.println(number + " 號(hào)運(yùn)動(dòng)員就位。");
                                  try {
                                      cb.await();
                                  } catch (InterruptedException | BrokenBarrierException ex) {
                                  }
                              }
                          }.start();
                      }
                      System.out.println("等待所有運(yùn)動(dòng)員就位...");
              

          運(yùn)行輸出(可能)為:

          運(yùn)動(dòng)員開始就位。
          1 號(hào)運(yùn)動(dòng)員到場(chǎng)并開始準(zhǔn)備...
          2 號(hào)運(yùn)動(dòng)員到場(chǎng)并開始準(zhǔn)備...
          等待所有運(yùn)動(dòng)員就位...
          3 號(hào)運(yùn)動(dòng)員到場(chǎng)并開始準(zhǔn)備...
          4 號(hào)運(yùn)動(dòng)員到場(chǎng)并開始準(zhǔn)備...
          6 號(hào)運(yùn)動(dòng)員到場(chǎng)并開始準(zhǔn)備...
          8 號(hào)運(yùn)動(dòng)員到場(chǎng)并開始準(zhǔn)備...
          5 號(hào)運(yùn)動(dòng)員到場(chǎng)并開始準(zhǔn)備...
          7 號(hào)運(yùn)動(dòng)員到場(chǎng)并開始準(zhǔn)備...
          1 號(hào)運(yùn)動(dòng)員就位。
          3 號(hào)運(yùn)動(dòng)員就位。
          8 號(hào)運(yùn)動(dòng)員就位。
          6 號(hào)運(yùn)動(dòng)員就位。
          2 號(hào)運(yùn)動(dòng)員就位。
          7 號(hào)運(yùn)動(dòng)員就位。
          5 號(hào)運(yùn)動(dòng)員就位。
          4 號(hào)運(yùn)動(dòng)員就位。
          比賽開始...

          最后看看 CyclicBarrierCountDownLatch 的主要異同:

          1. 兩者在構(gòu)造的時(shí)候都必須指定線程數(shù)量,而且該數(shù)量在構(gòu)造后不可修改。
          2. 前者可以傳入一個(gè) Runnable 對(duì)象,在任務(wù)完成后自動(dòng)調(diào)用,執(zhí)行者為某個(gè)子線程;后者可在 await 方法后手動(dòng)執(zhí)行一段代碼實(shí)現(xiàn)相同的功能,但執(zhí)行者為主線程。
          3. 前者在每個(gè)子線程上都進(jìn)行阻塞,然后一起放行;后者僅在主線程上阻塞一次。
          4. 前者可以重復(fù)使用;后者的倒計(jì)數(shù)器歸零后就作廢了。
          5. 兩者的內(nèi)部實(shí)現(xiàn)完全不同。
          主站蜘蛛池模板: 栾城县| 临沂市| 大悟县| 长海县| SHOW| 闽清县| 苍梧县| 仁寿县| 武定县| 河源市| 合江县| 孟州市| 栖霞市| 石狮市| 治多县| 监利县| 旬阳县| 开封县| 息烽县| 乌兰察布市| 保山市| 牙克石市| 尉氏县| 南岸区| 阜新| 五常市| 尚志市| 烟台市| 阳东县| 峨眉山市| 金沙县| 汨罗市| 五峰| 越西县| 武鸣县| 大庆市| 华池县| 宜州市| 乌拉特后旗| 福贡县| 咸丰县|