- 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)在终点,裁判员需要等待运动员都完成赛跑;