簡述
CountDownLatch是一個同步工具類,它允許一個或多個線程一直等待,直到其他線程的操作執行完后再執行。CountDownLatch 內部是用一個技術器實現的,計數器的初始值可以設為線程的數量,當一個線程任務結束之后,調用countDown()方法。當計數器值到達0時,它表示所有的線程已經完成了任務,然后在閉鎖上等待的線程就可以恢復執行任務。
簡單使用場景
有時候需要多個線程同時工作但是一個線程需要等其他線程工作結束后,才能開始。舉個例子,開啟多個線程分塊下載一個大文件,每個線程只下載固定的一截,最后由另外一個線程來拼接所有的分段,那么這時候我們可以考慮使用CountDownLatch來控制并發。
例子
class SecondThread extends Thread {
private CountDownLatch countDownLatch;
public SecondThread(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "start!");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
System.out.println(Thread.currentThread().getName() + "end!");
}
}
class FristThread extends Thread {
private CountDownLatch countDownLatch;
private Long time;
public FristThread(CountDownLatch countDownLatch, Long time) {
this.countDownLatch = countDownLatch;
this.time = time;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "start!");
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
System.out.println(Thread.currentThread().getName() + "end!");
}
}
@Test
public void testCountDownLatch() {
CountDownLatch countDownLatch = new CountDownLatch(2);
System.out.println("main start!");
FristThread thread1 = new FristThread(countDownLatch, 10000l);
thread1.setName("thread1");
thread1.start();
SecondThread thread2 = new SecondThread(countDownLatch);
thread2.setName("thread2");
thread2.start();
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main end!");
}
結果
main start!
thread1start!
thread2start!
thread2end!
thread1end!
main end!