提升開發效率的Java并發神器——閉鎖、同步屏障、信號量

guoxin77 7年前發布 | 18K 次閱讀 并發 Java Java開發

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();</code></pre>

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(); }</code></pre>

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(); }</code></pre>

 

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

 

 本文由用戶 guoxin77 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!