Java併發編程(七)——閉鎖、同步屏障、信號量詳解

轉自:http://blog.csdn.net/u010425776/article/details/54580082

1. 閉鎖:CountDownLatch

1.1 使用場景

若有多條線程,其中一條線程需要等到其他所有線程準備完所需的資源後才能運行,這樣的情況可以使用閉鎖。

1.2 代碼實現

// 初始化閉鎖,並設置資源個數
CountDownLatch latch = new CountDownLatch(2);

Thread t1 = new Thread( new Runnable(){
    public void run(){
        // 加載資源1
        加載資源的代碼……
        // 本資源加載完後,閉鎖-1
        latch.countDown();
    }
} ).start();

Thread t2 = new Thread( new Runnable(){
    public void run(){
        // 加載資源2
        資源加載代碼……
        // 本資源加載完後,閉鎖-1
        latch.countDown();
    }
} ).start();

Thread t3 = new Thread( new Runnable(){
    public void run(){
        // 本線程必須等待所有資源加載完後才能執行
        latch.await();
        // 當閉鎖數量爲0時,await返回,執行接下來的任務
        任務代碼……
    }
} ).start();

      2. 同步屏障:CyclicBarrier

      2.1 使用場景

      若有多條線程,他們到達屏障時將會被阻塞,只有當所有線程都到達屏障時才能打開屏障,所有線程同時執行,若有這樣的需求可以使用同步屏障。此外,當屏障打開的同時還能指定執行的任務。

      2.2 閉鎖 與 同步屏障 的區別

      • 閉鎖只會阻塞一條線程,目的是爲了讓該條任務線程滿足條件後執行;
      • 而同步屏障會阻塞所有線程,目的是爲了讓所有線程同時執行(實際上並不會同時執行,而是儘量把線程啓動的時間間隔降爲最少)。

      2.3 代碼實現

      // 創建同步屏障對象,並制定需要等待的線程個數 和 打開屏障時需要執行的任務
      CyclicBarrier barrier = new CyclicBarrier(3,new Runnable(){
          public void run(){
              //當所有線程準備完畢後觸發此任務
          }
      });
      
      // 啓動三條線程
      for( int i=0; i<3; i++ ){
          new Thread( new Runnable(){
              public void run(){
                  // 等待,(每執行一次barrier.await,同步屏障數量-1,直到爲0時,打開屏障)
                  barrier.await();
                  // 任務
                  任務代碼……
              }
          } ).start();
      }

          3. 信號量:Semaphore

          3.1 使用場景

          若有m個資源,但有n條線程(n>m),因此同一時刻只能允許m條線程訪問資源,此時可以使用Semaphore控制訪問該資源的線程數量。

          3.2 代碼實現

          // 創建信號量對象,並給予3個資源
          Semaphore semaphore = new Semaphore(3);
          
          // 開啓10條線程
          for ( int i=0; i<10; i++ ) {
              new Thread( new Runnbale(){
                  public void run(){
                      // 獲取資源,若此時資源被用光,則阻塞,直到有線程歸還資源
                      semaphore.acquire();
                      // 任務代碼
                      ……
                      // 釋放資源
                      semaphore.release();
                  }
              } ).start();
          }
              發表評論
              所有評論
              還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
              相關文章