CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如火箭发射需要检查很多步,例如10步,每一步都要检查完毕才能发射,这样就可以使用CountDownLatch类来进行。
构造函数:public
CountDownLatch(
int
count) { };
//参数count为计数值
主要方法:
1、await() 当前线程等待,直到count值为0才继续执行
2、boolean
await(
long
timeout, TimeUnit unit) 与await()类似,但不会一直等待,如果一段时间count值还没有变为0,则继续执行
3、countDown() { };
//将count值减1
例子1:火箭发射的例子,10个准备环节,准备结束后发射
public class RocketTest {
static CountDownLatch countDownLatch = new CountDownLatch(10);
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
int finalI = i;
new Thread(() -> {
try {
Thread.sleep((int)(Math.random()*3000));
System.out.println("检查环节" + finalI + "结束");
countDownLatch.countDown(); // 每个线程做一个检查,检查完毕就减一
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
new Thread(() -> {
try {
countDownLatch.await();
System.out.println("准备完毕,发射");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
执行结果
检查环节2结束
检查环节4结束
检查环节9结束
检查环节8结束
检查环节0结束
检查环节7结束
检查环节3结束
检查环节6结束
检查环节5结束
检查环节1结束
准备完毕,发射
例子2:模拟并发
public class CountDownLatchConcurrency {
static CountDownLatch countDownLatch = new CountDownLatch(10);
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
int finalI = i;
new Thread(() -> {
try {
// 每个线程休眠0-2秒
Thread.sleep((int)(Math.random()*2000));
System.out.println("线程" + finalI + "准备完毕");
// 计数器减一
countDownLatch.countDown();
// 等待其他的线程准备
countDownLatch.await();
System.out.println("\"线程\" + finalI + \"开始\"");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
执行的结果:
线程1准备完毕
线程5准备完毕
线程8准备完毕
线程2准备完毕
线程4准备完毕
线程6准备完毕
线程7准备完毕
线程3准备完毕
线程0准备完毕
线程9准备完毕
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"