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


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

有時候會有這樣的需求,多個線程同時工作,然后其中幾個可以隨意並發執行,但有一個線程需要等其他線程工作結束后,才能開始。舉個例子,開啟多個線程分塊下載一個大文件,每個線程只下載固定的一截,最后由另外一個線程來拼接所有的分段,那么這時候我們可以考慮使用CountDownLatch來控制並發。

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

示例

 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的方式。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM