概念原理
CountDownLatch
是 juc(java.util.concurrent)
包里的一个工具类,还有一起的CycliBarrier
和 Semaphore
CountDownLatch
这个类的作用是让 一个主线程
等待其他子线程执行完毕后
再执行。- 通过一个
计数器count
来实现的,计数器的初始值是子线程的数量
。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。 - 注意:
CountDownLatch
是一次性的,不能 reset count 值
核心参数和方法
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/bce8df1001be429389ba90ae2f0b3e4f.png)
- 一个核心参数
- 两个核心方法
countDown()
,让 count-1await()
,主任务等待的位置
两种应用场景
- 让 主任务 等待 所有子任务执行完毕后,再继续执行
- 让所有子任务同时执行,打印开始时间
实现代码
应用一:让 主任务 等待 所有子任务执行完毕后,再继续执行
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest01 {
public static void main(String[] args) throws InterruptedException {
int count = 3;
CountDownLatch latch = new CountDownLatch(count);
System.out.println("主任务开始...");
Random random = new Random();
for (int i = 0; i < count; i++) {
new Thread(() -> {
try {
int num = random.nextInt(8);
Thread.sleep(num * 1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println( " " + Thread.currentThread().getName() + " 子线程执行任务完毕");
latch.countDown();
}).start();
}
latch.await();
System.out.println("全部子任务执行完毕,主任务继续...");
Thread.sleep(3000);
System.out.println("主任务执行完毕");
}
}
执行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b8fd3cf042d54d3a88c3b71dcbf71bb3.png)
应用二:让所有子任务同时执行,打印出发时间
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest02 {
public static void main(String[] args) throws InterruptedException {
int count = 3;
CountDownLatch latch = new CountDownLatch(1);
for (int i = 0; i < count; i++) {
new Thread(() -> {
try {
latch.await();
System.out.println(Thread.currentThread().getName() + " 线程出发时间 " + System.currentTimeMillis());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
}
System.out.println("3 秒后开始...");
Thread.sleep(3000);
latch.countDown();
}
}
执行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/76daaa09868b49188dad739b4784d6e7.png)
应用二(扩展):让所有子任务同时执行,模拟百米冲刺
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest03 {
public static void main(String[] args) throws InterruptedException {
int count = 3;
CountDownLatch order = new CountDownLatch(1);
CountDownLatch answer = new CountDownLatch(count);
Random random = new Random();
for (int i = 0; i < count; i++) {
new Thread(() -> {
try {
order.await();
System.out.println(" " + Thread.currentThread().getName() + " 运动员出发...");
int num = random.nextInt(8);
Thread.sleep(num * 1000);
System.out.println( " " + Thread.currentThread().getName() + " 运动员到达终点,用时 " + num + " s");
answer.countDown();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
}
System.out.printf("口令:预备 -> 跑\n");
order.countDown();
answer.await();
System.out.println("所有运动员已到终点");
}
}
执行结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ea65b140e7fa46dd893c36515d68e550.png)