CountDownLatch
了解CounDownLatch
CountDownLatch是什么
CountDownLatch是Java1.5中被引入的,在java.util.concurrent包下的一个同步工具类,允许一个或多个线程等待,直到其他线程执行完后再执行
源码浅析
从CountDownLatch中可以看出,其核心技术就是AQS。
1 | public class CountDownLatch { |
Sync内部类
1 | private static final class Sync extends AbstractQueuedSynchronizer { |
继承了AQS里面的部分方法,同时重写了两个方法。作为CountDownLatch的同步控制。从CountDownLatch源码可以看出,核心是AQS,而调用AQS的是AQS的子类Sync。
await()方法
1 | public boolean await(long timeout, TimeUnit unit) |
由代码可以看到实际执行方法将由Sync这个继承自AQS的内部类执行。而上面展示的tryAcquireShareNanos()是AQS里面实现的方法。
countDown()方法
1 | public void countDown() { |
该方法跟await()这个方法是组合一起用的,里面也是使用了AQS的方法releaseShared()。
getCount()方法
1 | public long getCount() { |
这个方法里面调用了Sync实例里面的方法getCount(),返回当前count的值。
CountDownLatch工作
上面简单地介绍了CountDownLatch的内部实现(emmm虽然大部分都交给了AOS的实现),那么回到CountDownLatch这个名字本身,为什么叫CountDownLatch?
CountDownLatch = Count + Down + Latch:计数 + 减 + 门闩(shuan 第一声)
从名字中可以看出重点就是count, latch。count指的是内部维护了用户指定的count值,latch指的是其这个类展现出来的特性像门闩一样。
结合其用途理解就是,有线程A1, A2, A3, … An,线程B。B必须在各种A之前完成。此时用CountDownLatch,一开始设置好count(count大小习惯上等于A任务的数量),然后同时将这个CountDownLatch设置给A,B任务(两者调用latch的区别就是A任务调用countDown(),而B任务调用awai()方法)。A任务在结束时调用countDown()方法,B任务一开始调用await()方法。此时latch就像一个门闩,在B执行之前,阻隔了所有A任务。
示例代码:
1 | public class TestCountDownLatch2 { |
执行结果:
(结果说明:别问我为什么是顺序执行,虚拟机,操作系统不一样,运行结果就不一样)
上述代码中,main线程就是所说的B线程,而new出来的所有线程就是A线程,main线程中的打印语句(”全部线程已执行完毕”)等到所有10个线程执行完成了再执行。