java併發程式設計之使用 CountDownLatch 控制多個執行緒執行順序
阿新 • • 發佈:2018-11-08
有時候會有這樣的需求,多個執行緒同時工作,然後其中幾個可以隨意併發執行,但有一個執行緒需要等其他執行緒工作結束後,才能開始。舉個例子,開啟多個執行緒分塊下載一個大檔案,每個執行緒只下載固定的一截,最後由另外一個執行緒來拼接所有的分段,那麼這時候我們可以考慮使用CountDownLatch來控制併發。
CountDownLatch是JAVA提供在java.util.concurrent包下的一個輔助類,可以把它看成是一個計數器,其內部維護著一個count計數,只不過對這個計數器的操作都是原子操作,同時只能有一個執行緒去操作這個計數器,CountDownLatch通過建構函式傳入一個初始計數值,呼叫者可以通過呼叫CounDownLatch物件的cutDown()方法,來使計數減1;如果呼叫物件上的await()方法,那麼呼叫者就會一直阻塞在這裡,直到別人通過cutDown方法,將計數減到0,才可以繼續執行。
示例
import java.util.concurrent.CountDownLatch; public class Sample { /** * 計數器,用來控制執行緒 * 傳入引數2,表示計數器計數為2 */ private final static CountDownLatch mCountDownLatch = new CountDownLatch(2); /** * 示例工作執行緒類 */ private static class WorkingThread extends Thread { private final String mThreadName; private final int mSleepTime; public WorkingThread(String name, int sleepTime) { mThreadName = name; mSleepTime = sleepTime; } @Override public void run() { System.out.println("[" + mThreadName + "] started!"); try { Thread.sleep(mSleepTime); } catch (InterruptedException e) { e.printStackTrace(); } mCountDownLatch.countDown(); System.out.println("[" + mThreadName + "] end!"); } } /** * 示例執行緒類 */ private static class SampleThread extends Thread { @Override public void run() { System.out.println("[SampleThread] started!"); try { // 會阻塞在這裡等待 mCountDownLatch 裡的count變為0; // 也就是等待另外的WorkingThread呼叫countDown() mCountDownLatch.await(); } catch (InterruptedException e) { } System.out.println("[SampleThread] end!"); } } public static void main(String[] args) throws Exception { // 最先run SampleThread new SampleThread().start(); // 執行兩個工作執行緒 // 工作執行緒1執行5秒 new WorkingThread("WorkingThread1", 5000).start(); // 工作執行緒2執行2秒 new WorkingThread("WorkingThread2", 2000).start(); } }
執行結果:
[SampleThread] started!
[WorkingThread1] started!
[WorkingThread2] started!
[WorkingThread2] end!
[WorkingThread1] end!
[SampleThread] end!
達到了目的。當然還有其他方式可以做到這樣的效果,本文僅僅是介紹了一種使用CountDownLatch的方式。