java.util.concurrent.CountDownLatch工具类
CountDown n. 倒数 latch n. 门闩 latch on 占有抓住、理解 one the latch 关着但不上锁
She latch on to your notion. 她理解你的意见。 To open the gate, lift up the latch。要打开大门,先把门闩提起来
CountDownLatch -> 倒数锁存器
CountDownLatch可以看作计数器,同时只能有一个线程去操作计数器也只有一个线程减少这个计数器里面的一个值
public class CountDownLatch extends Object
主要功能: 主线程调用await()实现线程阻塞等待其他线程执行完毕(其他线程执行过程中执行CountDownLatch对象的countDown()方法进行倒计时)。
CountDownLatch类主要方法:
| 变量和类型 | 方法 | 描述 |
|---|---|---|
| CountDownLatch(int count) | 构造一个给定计数初始化的CountDownLatch | |
| void | await() | 调用await()方法的线程等待直到计数为0 |
| void | countDown() | 计数器计数,当计数为0释放所有等待线程 |
| long | getCount() | 返回当前计数数字 |
| String | toString() | 返回标识锁存器的字符串及其状态 |
应用场景:启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行.
🌰实例
/**
* @author :Wangzhuang2
* @version : 1.0.0
* @date :Created in 2020/11/10 9:29
* DESC 当前端人员和后端人员完成工作,项目经理宣告项目的开始和结束!
*/
// 前端人员
class FrontEndStaff implements Runnable{
private CountDownLatch countDownLatch;
private String departmentName;
FrontEndStaff(CountDownLatch countDownLatch, String departmentName){
this.countDownLatch = countDownLatch;
this.departmentName = departmentName;
}
@Override
public void run() {
System.out.println("【"+departmentName+"】前端工作开始》》》");
doWork();
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(5)); // 慢一点儿
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("【"+departmentName+"】前端界面设计结束!");
this.countDownLatch.countDown(); // 计时器⏲计数
}
private void doWork(){
System.out.println("前端界面设计处理中......!");
}
}
// 后端人员
class BackEndStaff implements Runnable{
private CountDownLatch countDownLatch;
private String departmentName;
BackEndStaff(CountDownLatch countDownLatch, String departmentName){
this.countDownLatch = countDownLatch;
this.departmentName = departmentName;
}
@Override
public void run() {
System.out.println("【"+departmentName+"】后端工作开始》》》");
doWork();
try {
TimeUnit.SECONDS.sleep(new Random().nextInt(5)); // // 慢一点儿
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("【"+departmentName+"】后端工作结束!");
this.countDownLatch.countDown(); // 计时器⏲计数
}
private void doWork(){
System.out.println("后端程序设计和业务实现中...");
}
}
// 项目经理
class ProjectManager implements Runnable{
private CountDownLatch countDownLatch;
ProjectManager(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println(">>>>项目启动<<<<");
try {
this.countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(">>>>项目结束<<<<");
}
}
public class TestDemo03 {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(2);
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new FrontEndStaff(countDownLatch, "前端部门"));
executorService.execute(new BackEndStaff(countDownLatch, "后端部门"));
executorService.execute(new ProjectManager(countDownLatch));
executorService.shutdown();
}
}
/*
>>>>项目启动<<<<
【后端部门】后端工作开始》》》
【前端部门】前端工作开始》》》
后端程序设计和业务实现中...
前端界面设计处理中......!
【前端部门】前端界面设计结束!
【后端部门】后端工作结束!
>>>>项目结束<<<<
*/
总结
🏳🌈CountDownLatch是一个计数器,计数器的初始值并不一定是线程的数量,完全可以一个线程countDown两次。
🏳🌈所述await种方法阻塞,直到当前计数达到零由于的调用countDown()方法,之后所有等待的线程被释放和任何后续调用await立即返回。 这是一次性现象 - 计数无法重置
学而不思则罔,思而不学则殆!

浙公网安备 33010602011771号