###CountDownLatch 是什么
倒计时锁。
让1个或多个线程等待,让指定的多个线程全部都运行完成以后,再执行等待线程。
###实例
例子:老板要等3个工人都干完活,再做总结
public class Worker implements Runnable{
private CountDownLatch countDownLatch;
private String name;
public Worker(CountDownLatch countDownLatch,String name){
this.countDownLatch=countDownLatch;
this.name=name;
}
public void run() {
doWork();
try {
Thread.sleep(2000);
countDownLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
private void doWork(){
System.out.println(this.name+":正在干活!");
}
}
public class Boss implements Runnable{
private CountDownLatch countDownLatch;
private String name;
public Boss(CountDownLatch countDownLatch,String name){
this.countDownLatch=countDownLatch;
this.name=name;
}
public void run() {
System.out.println(this.name+":老板正在等待工人干活");
try {
this.countDownLatch.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(this.name+":工人干完活了,老板开始总结。。。。。");
}
}
public class CountDownLatchTest {
public static void main(String[] args) {
CountDownLatch countDownLatch=new CountDownLatch(3);
Worker worker1=new Worker(countDownLatch,"张三");
Worker worker2=new Worker(countDownLatch,"李四");
Worker worker3=new Worker(countDownLatch,"王五");
Boss boss=new Boss(countDownLatch,"老板");
new Thread(boss).start();
new Thread(worker1).start();
new Thread(worker2).start();
new Thread(worker3).start();
}
}
###实现原理
CountDownLatch是基于AQS的共享模式实现的
AQS 有个state 记录,这个state 值就是 需要等待N个线程执行完以后,再执行其他的线程中的N 。
countDownLatch.countDown(); 没执行一次,state(CAS执行) 就会减1.
直到state为0的时候,再去执行等待中的线程。
AbstractQueueSynchronizer(同步器) 类中有1个FIFO链式队列,叫CLH队列,该队列是阻塞队列,是竞争锁的队列。
AbstractQueueSynchronizer 中有个内部类。ConditionObject继承了Condition接口,ConditionObject 类中维护了1个等待队列(该队列是线程安全的,因为要用到condition,必须先获取到锁),该队列是用condition.await()方法后,将等待中的队列,添加到等待队列中。
condition.await() 的实现是 LockSupport.park()方法。唤醒condition.signal()的实现是LockSupport.unpark()方法。
LockSupport类中的park和unpark方法,都是用Unsafe类中的JNI接口使用CAS原理实现的。