JAVA並發,CountDownLatch使用

來源:互聯網
上載者:User

標籤:

該文章轉自:http://www.itzhai.com/the-introduction-and-use-of-a-countdownlatch.html

CountDownLatch

1、類介紹

一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。用給定的計數 初始化 CountDownLatch。由於調用了 countDown() 方法,所以在當前計數到達零之前,await 方法會一直受阻塞。之後,會釋放所有等待的線程,await 的所有後續調用都將立即返回。這種現象只出現一次——計數無法被重設。 一個線程(或者多個), 等待另外N個線程完成某個事情之後才能執行

 

2、使用情境 在一些應用場合中,需要等待某個條件達到要求後才能做後面的事情;同時當線程都完成後也會觸發事件,以便進行後面的操作。 這個時候就可以使用CountDownLatch。CountDownLatch最重要的方法是countDown()和await(),前者主要是倒數一次,後者是等待倒數到0,如果沒有到達0,就只有阻塞等待了。3、方法說明countDown
public void countDown()
遞減鎖存器的計數,如果計數到達零,則釋放所有等待的線程。如果當前計數大於零,則將計數減少。如果新的計數為零,出於線程調度目的,將重新啟用所有的等待線程。

 

如果當前計數等於零,則不發生任何操作。

await
public boolean await(long timeout,                     TimeUnit unit)              throws InterruptedException
使當前線程在鎖存器倒計數至零之前一直等待,除非線程被中斷或超出了指定的等待時間。如果當前計數為零,則此方法立刻返回  true 值。

 

如果當前計數大於零,則出於線程調度目的,將禁用當前線程,且在發生以下三種情況之一前,該線程將一直處於休眠狀態:

  • 由於調用 countDown() 方法,計數到達零;或者
  • 其他某個線程中斷當前線程;或者
  • 已超出指定的等待時間。

如果計數到達零,則該方法返回 true 值。

如果當前線程:

  • 在進入此方法時已經設定了該線程的中斷狀態;或者
  • 在等待時被中斷,

則拋出 InterruptedException,並且清除當前線程的已中止狀態。如果超出了指定的等待時間,則傳回值為 false。如果該時間小於等於零,則此方法根本不會等待。

 

參數:
timeout - 要等待的最長時間
unit -  timeout 參數的時間單位。
返回:
如果計數到達零,則返回  true;如果在計數到達零之前超過了等待時間,則返回  false
拋出:
InterruptedException - 如果當前線程在等待時被中斷
4、相關執行個體
 1 public class CountDownLatchTest { 2  3     // 類比了100米賽跑,10名選手已經準備就緒,只等裁判一聲令下。當所有人都到達終點時,比賽結束。 4     public static void main(String[] args) throws InterruptedException { 5  6         // 開始的倒數鎖  7         final CountDownLatch begin = new CountDownLatch(1);   8  9         // 結束的倒數鎖 10         final CountDownLatch end = new CountDownLatch(10);  11 12         // 十名選手 13         final ExecutorService exec = Executors.newFixedThreadPool(10);  14 15         for (int index = 0; index < 10; index++) {16             final int NO = index + 1;  17             Runnable run = new Runnable() {18                 public void run() {  19                     try {  20                         // 如果當前計數為零,則此方法立即返回。21                         // 等待22                         begin.await();  23                         Thread.sleep((long) (Math.random() * 10000));  24                         System.out.println("No." + NO + " arrived");  25                     } catch (InterruptedException e) {  26                     } finally {  27                         // 每個選手到達終點時,end就減一28                         end.countDown();29                     }  30                 }  31             };  32             exec.submit(run);33         }  34         System.out.println("Game Start");  35         // begin減一,開始遊戲36         begin.countDown();  37         // 等待end變為0,即所有選手到達終點38         end.await();  39         System.out.println("Game Over");  40         exec.shutdown();  41     }42 }

5、輸出結果

Game Start
No.9 arrived
No.6 arrived
No.8 arrived
No.7 arrived
No.10 arrived
No.1 arrived
No.5 arrived
No.4 arrived
No.2 arrived
No.3 arrived
Game Over  資料補充,下面的例子來源於thinking in java(跟上面的例子不同之處在於上面的例子是一個任務等到多個任務執行完成,而thinking in java的就進階一些了,是多個任務等到多個任務執行完成解鎖): 代碼1:
 1 package com.cakushin.thread.countdownlatch; 2  3 import java.util.Random; 4 import java.util.concurrent.CountDownLatch; 5  6 public class TaskPortion implements Runnable { 7     private static int counter = 0; 8     private final int id = counter++; 9     private static Random rand = new Random(47);10     private final CountDownLatch latch;11     12     public TaskPortion(CountDownLatch latch){13         this.latch = latch;14     }15 16     @Override17     public void run() {18         try {19             doWork();20             latch.countDown();21         } catch (InterruptedException e) {22             e.printStackTrace();23         }24     }25 26     private void doWork() throws InterruptedException {27         Thread.sleep(rand.nextInt(2000));28         System.out.println(this + " completed!");29     }30     31     public String toString(){32         return String.format("%1$-3d", id);33     }34 35 }

代碼2:

 1 package com.cakushin.thread.countdownlatch; 2  3 import java.util.concurrent.CountDownLatch; 4  5 public class WaitingTask implements Runnable { 6     private static int counter = 0; 7     private final int id = counter++; 8     private final CountDownLatch latch; 9     10     public WaitingTask(CountDownLatch latch){11         this.latch = latch;12     }13 14     @Override15     public void run() {16         try {17             latch.await();18             System.out.println("Latch barrier passed for " + this);19         } catch (InterruptedException e) {20             System.out.println(this + " interrupted");21         }22     }23     24     public String toString(){25         return String.format("WatingTask %1$-3d", id);26     }27 28 }

代碼3:

 1 package com.cakushin.thread.countdownlatch; 2  3 import java.util.concurrent.CountDownLatch; 4 import java.util.concurrent.ExecutorService; 5 import java.util.concurrent.Executors; 6  7 public final class CountDownLatchDemo { 8  9     static final int SIZE = 100;10     11     /**12      * @author Administrator13      * @param args14      */15     public static void main(String[] args) {16         ExecutorService exec = Executors.newCachedThreadPool();17         CountDownLatch latch = new CountDownLatch(SIZE);18         for(int i = 0; i < 10; i++){19             exec.execute(new WaitingTask(latch));20         }21         for(int i = 0; i < 100; i++){22             exec.execute(new TaskPortion(latch));23         }24         System.out.println("Launched all tasks");25         exec.shutdown();26     }27 28 }

 

 

JAVA並發,CountDownLatch使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.