CountDownLatch源码分析
2024-09-01 00:06:15
CountDownLatch、Semaphore(信号量)和ReentrantReadWriteLock.ReadLock(读锁)都采用AbstractOwnableSynchronizer共享排队的方式实现。
关于AbstractQueuedSynchronizer中的独占锁和共享锁,请参考ReentrantLock(http://www.cnblogs.com/bjorney/p/8040085.html)和ReentrantReadWriteLock(http://www.cnblogs.com/bjorney/p/8064268.html)
1. CountDownLatch
public class CountDownLatch {
private final Sync sync; public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count); // sync的锁状态(锁计数)state = count
} public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1); // 参数1并未使用
} public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
} public void countDown() {
sync.releaseShared(1); // sync的锁状态(锁计数)state--,见Sync.tryReleaseShared
} ... ... }
2. CountDownLatch.sync
private static final class Sync extends AbstractQueuedSynchronizer {
Sync(int count) {
setState(count); // sync的锁状态(锁计数)state = count
} protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1; // 若state > 0(尝试取锁失败),则当前线程进入SyncQueue排队等锁
} protected boolean tryReleaseShared(int releases) {
for (;;) {
// CAS(state)失败将回到此处
int c = getState(); /*记录state*/
if (c == 0)
return false;
int nextc = c - 1;
if (compareAndSetState(c, nextc)) /*CAS设置state -= 1*/
return nextc == 0; // 若state为0(尝试释放锁成功),则唤醒所有在SyncQueue排队等锁的节点(线程)
}
}
}
最新文章
- ASP.NET Core 中文文档 第三章 原理(11)在多个环境中工作
- Windows 10设置桌面图标间距、窗口的背景颜色、选中文字的背景颜色
- Understanding Linux /proc/cpuinfo
- UNDO表空间设置
- for-in语句
- JAX-WS 学习二:基于WEB容器,发布WebService
- flexigrid 修改json格式
- zend studio 使用断点调试
- C# 从零开始 vol.2
- NC帮助文档网址
- 利用face_recognition库裁取人脸
- html笔记第一天
- dpkg: 处理软件包 xxx (--configure)时出错 解决办法
- HTML怎么实现字体加粗
- VS2017编译SNMP++步骤记录
- [SDOI2017]树点涂色
- 行为链分析zipkin
- 利用Linux的硬连接删除MySQL大文件
- 递归n!
- Webpack 常见静态资源处理 - 模块加载器(Loaders)+ExtractTextPlugin插件