CountDownLatch 的理解
- 功能
功能方面,该类可以用于很多并发场景,比如用于多个线程的统一开关,只要把初始count设为1,就可以实现类似于一键触发的功能,这个可以用于多线程性能测试的内容;还有一种情况是用于为某个事件准备多个资源的情况,比如赛跑的情况~~
2.原理
CountDownLatch 是同一个包含一个内部类,该类继承于AbstractQueuedSynchronizer(AQS),使用的是AQS共享锁的机制,这样可以保证在count将为零时,能够用传递的方式将队列内等待的线程全部唤醒,同时放出去。
实现CountDownLatch 细节
- 简单版api
await() // 阻塞当前线程
countdown() // 是状态值减一,当为零时释放所有在阻塞的线程
CountDownLatch (int count) //构造器 初始化状态值
2.实现关键点
- 阻塞当前线程
- 原子的实现count减法
- 统一释放所有等待线程
这里按照Doug lea大师在java并发库里的写法,实现起来太麻烦了,望而却步。
考虑要实现上面三个功能,我就想到了同样是基于AQS的读写锁,读锁可以hold住所有获取读锁的线程,写锁的话,大家都能获取,并且当读锁释放是,能够实现全部唤醒。
3.问题点与解决办法
这里的难点在于创建Latch的时候,就要hold住到来await的线程。
所以读锁的加锁和解锁,都是在MyLatch初始化的时候,在构造器里新开启一个线程完成的,利用死循环检测状态值,实现第一时间触发。
具体实现
MyCountDownLatch 利用读写锁实现
MyCountDownLatch
MyCountDownLatchTest
下面是运行时的输出结果
run result
PS:认识的微软大神向我推他写的并发库,说是最轻量的,这里粘贴下地址,来日学习:
地址