paulwong

          CountDownLatch、CyclicBarrier和Semaphore

          CountDownLatch、CyclicBarrier和Semaphore這三個并發(fā)輔助類,可以在線程中呼叫,使得線程暫停等,但各有不同。

          • CountDownLatch
          1、初始化,并傳入計數(shù)器
          2、向不同的線程傳入CountDownLatch實例
          3、如果在某一線程中呼叫await(),則此線程被掛起,直到計數(shù)器為0,才往下執(zhí)行
          4、如果在某一線程中呼叫countDown(),計數(shù)器減1
          5、最終如果計數(shù)器值為0時,則CountDownLatch實例不再起作用了,即為一次性的

          • CyclicBarrier
          1、初始化,并傳入計數(shù)器值,也可傳入一個Runnable類,會在計數(shù)器為0時,被執(zhí)行
          2、向不同的線程傳入CyclicBarrier實例
          3、如果在某一線程中呼叫await(),則此線程被掛起,直到計數(shù)器為0,才往下執(zhí)行
          4、其他線程呼叫await(),則此線程被掛起,直到計數(shù)器為0,才往下執(zhí)行
          5、最終如果計數(shù)器值為0時,則CyclicBarrier實例會將計數(shù)器值恢復(fù),又可重用

          • Semaphore
          1、初始化,并傳入計數(shù)器值
          2、向不同的線程傳入Semaphore實例
          3、如果在某一線程中呼叫acquire(),則Semaphore實例會將計數(shù)器值減1,如果計數(shù)器值為-1,則將計數(shù)器值置為0,此線程被掛起,直到計數(shù)器值大于1時,才往下執(zhí)行
          4、此線程需呼叫release(),使得計數(shù)器值+1,以便其他線程在計數(shù)器值為0時不受阻


          CountDownLatch 例子:
          public class Test {
               public static void main(String[] args) {   
                   final CountDownLatch latch = new CountDownLatch(2);
                    
                   new Thread(){
                       public void run() {
                           try {
                               System.out.println("子線程"+Thread.currentThread().getName()+"正在執(zhí)行");
                              Thread.sleep(3000);
                              System.out.println("子線程"+Thread.currentThread().getName()+"執(zhí)行完畢");
                              latch.countDown();
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                       };
                   }.start();
                    
                   new Thread(){
                       public void run() {
                           try {
                               System.out.println("子線程"+Thread.currentThread().getName()+"正在執(zhí)行");
                               Thread.sleep(3000);
                               System.out.println("子線程"+Thread.currentThread().getName()+"執(zhí)行完畢");
                               latch.countDown();
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                       };
                   }.start();
                    
                   try {
                       System.out.println("等待2個子線程執(zhí)行完畢");
                      latch.await();
                      System.out.println("2個子線程已經(jīng)執(zhí)行完畢");
                      System.out.println("繼續(xù)執(zhí)行主線程");
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
               }
          }

          結(jié)果:
          線程Thread-0正在執(zhí)行
          線程Thread-1正在執(zhí)行
          等待2個子線程執(zhí)行完畢
          線程Thread-0執(zhí)行完畢
          線程Thread-1執(zhí)行完畢
          2個子線程已經(jīng)執(zhí)行完畢
          繼續(xù)執(zhí)行主線程


          CyclicBarrier例子:
          public class Test {
              public static void main(String[] args) {
                  int N = 4;
                  CyclicBarrier barrier  = new CyclicBarrier(N,new Runnable() {
                      @Override
                      public void run() {
                          System.out.println("當(dāng)前線程"+Thread.currentThread().getName());   
                      }
                  });
                   
                  for(int i=0;i<N;i++)
                      new Writer(barrier).start();
              }
              static class Writer extends Thread{
                  private CyclicBarrier cyclicBarrier;
                  public Writer(CyclicBarrier cyclicBarrier) {
                      this.cyclicBarrier = cyclicBarrier;
                  }
           
                  @Override
                  public void run() {
                      System.out.println("線程"+Thread.currentThread().getName()+"正在寫入數(shù)據(jù)");
                      try {
                          Thread.sleep(5000);      //以睡眠來模擬寫入數(shù)據(jù)操作
                          System.out.println("線程"+Thread.currentThread().getName()+"寫入數(shù)據(jù)完畢,等待其他線程寫入完畢");
                          cyclicBarrier.await();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }catch(BrokenBarrierException e){
                          e.printStackTrace();
                      }
                      System.out.println("所有線程寫入完畢,繼續(xù)處理其他任務(wù)");
                  }
              }
          }

          執(zhí)行結(jié)果:
          線程Thread-0正在寫入數(shù)據(jù)
          線程Thread-1正在寫入數(shù)據(jù)
          線程Thread-2正在寫入數(shù)據(jù)
          線程Thread-3正在寫入數(shù)據(jù)
          線程Thread-0寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
          線程Thread-1寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
          線程Thread-2寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
          線程Thread-3寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
          當(dāng)前線程Thread-3
          所有線程寫入完畢,繼續(xù)處理其他任務(wù)
          所有線程寫入完畢,繼續(xù)處理其他任務(wù)
          所有線程寫入完畢,繼續(xù)處理其他任務(wù)
          所有線程寫入完畢,繼續(xù)處理其他任務(wù)


          Semaphore例子:
          public class Test {
              public static void main(String[] args) {
                  int N = 8;            //工人數(shù)
                  Semaphore semaphore = new Semaphore(5); //機器數(shù)目
                  for(int i=0;i<N;i++)
                      new Worker(i,semaphore).start();
              }
               
              static class Worker extends Thread{
                  private int num;
                  private Semaphore semaphore;
                  public Worker(int num,Semaphore semaphore){
                      this.num = num;
                      this.semaphore = semaphore;
                  }
                   
                  @Override
                  public void run() {
                      try {
                          semaphore.acquire();
                          System.out.println("工人"+this.num+"占用一個機器在生產(chǎn)");
                          Thread.sleep(2000);
                          System.out.println("工人"+this.num+"釋放出機器");
                          semaphore.release();           
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }

          執(zhí)行結(jié)果:
          工人0占用一個機器在生產(chǎn)
          工人1占用一個機器在生產(chǎn)
          工人2占用一個機器在生產(chǎn)
          工人4占用一個機器在生產(chǎn)
          工人5占用一個機器在生產(chǎn)
          工人0釋放出機器
          工人2釋放出機器
          工人3占用一個機器在生產(chǎn)
          工人7占用一個機器在生產(chǎn)
          工人4釋放出機器
          工人5釋放出機器
          工人1釋放出機器
          工人6占用一個機器在生產(chǎn)
          工人3釋放出機器
          工人7釋放出機器
          工人6釋放出機器

          https://www.cnblogs.com/dolphin0520/p/3920397.html

          https://juejin.im/post/5aeec3ebf265da0ba76fa327

          posted on 2019-09-24 10:18 paulwong 閱讀(336) 評論(0)  編輯  收藏 所屬分類: J2SE

          主站蜘蛛池模板: 油尖旺区| 泰兴市| 和顺县| 泽库县| 富川| 鲜城| 翁牛特旗| 伊春市| 丹阳市| 蓬溪县| 白城市| 多伦县| 蒙阴县| 乌拉特中旗| 德令哈市| 固始县| 康定县| 松原市| 科尔| 三都| 盐山县| 仪征市| 卢氏县| 茶陵县| 芦溪县| 金乡县| 通城县| 东山县| 星子县| 马龙县| 平舆县| 九台市| 陕西省| 东山县| 苍溪县| 肥东县| 红河县| 馆陶县| 青州市| 尼木县| 新营市|