使用 CountDownLatch 控制多個線程執行順序

已同步更新至:http://dxjia.cn/2015/08/countdownlatch-use/    java

有時候會有這樣的需求,多個線程同時工做,而後其中幾個能夠隨意併發執行,但有一個線程須要等其餘線程工做結束後,才能開始。舉個例子,開啓多個線程分塊下載一個大文件,每一個線程只下載固定的一截,最後由另一個線程來拼接全部的分段,那麼這時候咱們能夠考慮使用CountDownLatch來控制併發。併發

    CountDownLatch是JAVA提供在java.util.concurrent包下的一個輔助類,能夠把它當作是一個計數器,其內部維護着一個count計數,只不過對這個計數器的操做都是原子操做,同時只能有一個線程去操做這個計數器,CountDownLatch經過構造函數傳入一個初始計數值,調用者能夠經過調用CounDownLatch對象的cutDown()方法,來使計數減1;若是調用對象上的await()方法,那麼調用者就會一直阻塞在這裏,直到別人經過cutDown方法,將計數減到0,才能夠繼續執行。ide

示例

 1 import java.util.concurrent.CountDownLatch;
 2 
 3 public class Sample {
 4     /**
 5      * 計數器,用來控制線程
 6      * 傳入參數2,表示計數器計數爲2
 7      */
 8     private final static CountDownLatch mCountDownLatch = new CountDownLatch(2);
 9 
10     /**
11      * 示例工做線程類
12      */
13     private static class WorkingThread extends Thread {
14         private final String mThreadName;
15         private final int mSleepTime;
16         public WorkingThread(String name, int sleepTime) {
17             mThreadName = name;
18             mSleepTime = sleepTime;
19         }
20         
21         @Override
22         public void run() {
23             System.out.println("[" + mThreadName + "] started!");
24             try {  
25                     Thread.sleep(mSleepTime);  
26             } catch (InterruptedException e) {  
27                     e.printStackTrace();  
28             }
29             mCountDownLatch.countDown();
30             System.out.println("[" + mThreadName + "] end!"); 
31         }
32     }
33     
34     /**
35      * 示例線程類
36      */
37     private static class SampleThread extends Thread {
38         
39         @Override
40         public void run() {
41             System.out.println("[SampleThread] started!");
42             try {
43                 // 會阻塞在這裏等待 mCountDownLatch 裏的count變爲0;
44                 // 也就是等待另外的WorkingThread調用countDown()
45                 mCountDownLatch.await();
46             } catch (InterruptedException e) {
47                 
48             }
49             System.out.println("[SampleThread] end!");
50         }
51     }
52     
53     public static void main(String[] args) throws Exception {
54         // 最早run SampleThread
55         new SampleThread().start();
56         // 運行兩個工做線程
57         // 工做線程1運行5秒
58         new WorkingThread("WorkingThread1", 5000).start();
59         // 工做線程2運行2秒
60         new WorkingThread("WorkingThread2", 2000).start();
61     }
62 }

 

運行結果:

[SampleThread] started!
[WorkingThread1] started!
[WorkingThread2] started!
[WorkingThread2] end!
[WorkingThread1] end!
[SampleThread] end!函數

達到了目的。固然還有其餘方式能夠作到這樣的效果,本文僅僅是介紹了一種使用CountDownLatch的方式。spa

相關文章
相關標籤/搜索