- CountDownLatch是一个同步辅助类,直译过来是倒计数(CountDown)门闩(Latch)。倒计数不用说,门闩的意思就是阻止前进。在完成一组在正在其他线程中执行的线程任务之前,CountDownLatch允许一个或多个线程(也就是前一句所指的其他线程)一直等待。用给定的计数初始化CountDownLatch。由于调用了 countDown() 方法,所以在当前计数器到达零之前,await() 方法会一直受阻塞。之后会释放所有等待线程。
- 应用场景
1、开5个线程去下载,当5个线程都执行完了才算下载成功。
2、当用户多文件上传时,可以采用多个线程上传,当多个文件都上传成功了的时候才算上传完成。
3、三个程序开发一个项目,当三个人分别把活儿干完了,项目才算完成。
/**
* 模拟3个程序员干活,3个人都完成了项目才能上线
*/
public class CountDownLatchTest2 {
//主线程
public static void main(String[] args) throws Exception {
CountDownLatch latch = new CountDownLatch(3);
//创建三个线程
Thread thread = new Thread(new Worker("Jack 程序员1 :", latch));
Thread thread1 = new Thread(new Worker("Kate 程序员2 :", latch));
Thread thread2 = new Thread(new Worker("Tom 程序员3 :", latch));
thread.start();
thread1.start();
thread2.start();
//使得当前线程(主线程)一直等待,知道锁存器倒数为0
latch.await();
System.out.println("主线程结束,项目上线完成");
}
static class Worker implements Runnable {
private String workerName;
private CountDownLatch latch;
public Worker(String workerName, CountDownLatch latch) {
this.workerName = workerName;
this.latch = latch;
}
public void run() {
//模拟干活
try {
System.out.println("worker : " + workerName + " is begin.");
Thread.sleep(1000L);
System.out.println("worker : " + workerName + " is end.");
} catch (InterruptedException e) {
e.printStackTrace();
}
//递减锁存器,并计数
latch.countDown();
}
}
}
4、百米赛跑,有3个人参加,都在起跑线上等待裁判员发出起跑命令,当裁判员发出命令后,运动员在跑道上赛跑;此时的裁判就需要在终点等待所有运动都过终点线以后,裁判员才能给出每个人的成绩并判断谁是第一名。我们分析这个场景,(1)运动员开跑需要等待裁判员发号命令;(2)在终点,裁判员需要等待运动员都完成赛跑;