CountDownLatch 是java.util.concurrent包中一个类,顾名思义就是倒计时锁,是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待
闭锁可以延迟线程的进度直到其到达终止状态,闭锁可以用来确保某些活动直到其他活动都完成才继续执行:
- 确保某个计算在其需要的所有资源都被初始化之后才继续执行;
- 确保某个服务在其依赖的所有其他服务都已经启动之后才启动;
- 等待直到某个操作所有参与者都准备就绪再继续执行。
CountDownLatch有一个正数计数器,countDown()方法对计数器做减操作,await()方法等待计数器达到0。所有await的线程都会阻塞直到计数器为0或者等待线程中断或者超时
其内部类Sync同样继承了AQS并重写了tryAcquireShared和tryReleaseShared方法。同时也可以表明CountDownLatch是基于共享锁模式的。
- new CountDownLatch(2) 构造方法初始化数值
- countDown() 支持多线程调用 每次调用减一
- getCount() 获取当前计数器的数值
- await() 阻塞线程至计数器为0时唤醒所有线程
- await(long timeout, TimeUnit unit) 线程在指定的时间单位内进入WAITING状态,如果超过这个时间则自动唤醒,程序继续向下运行。参数timeout是等待的时间,而unit参数是时间的单位。
代码
例一
class bbb implements Runnable{
private final CountDownLatch countDown;
public bbb(CountDownLatch countDown) {
this.countDown = countDown;
}
public void run() {
countDown.countDown();
System.out.println("-----"+countDown.getCount());
System.out.println(countDown.getCount());
try {
countDown.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class aaa{
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDown = new CountDownLatch(2);
for (int i = 0; i < 2; ++i) {
new Thread(new bbb(countDown)).start();
}
}
}
例二
把阻塞的位置改变
public void run() {
countDown.countDown();
System.out.println("-----"+countDown.getCount());
try {
countDown.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(countDown.getCount());
}
打印
例一
-----1
1
-----0
0
例二
-----1
-----0
0
0
根据例一二的打印顺序可以看出 多线程的运行轨迹, await() 方法只有在 countDown() 方法 将计数器的值减到0时才会执行后面代码,否则一直阻塞 或者 等待线程中断 或 者超时