浅析ConcurrentHashMap类

本人几年前阅读了ConcurrentHashMap源代码,并画了几张类图,想分享一下。
在这里插入图片描述
上图是ConcurrentHashMap类图
在这里插入图片描述
上图是线程等待队列示意图;
使用的标志位+队列的方式,记录锁、竞争、释放等一系列独占的状态
AQS只是维护一个状态,一个控制各个线程何时可以访问的状态,它只对状态负责,而这个状态表示什么含义,由子类自己去定义。
在ReentrantLock中,表示加锁的次数,在CountDownLatch中,则表示CountDownLatch的计数器的初始大小.;

在等待锁队列中增加删除节点时,必须维护队列结构的正确性
操作序列:先修改node.prev、再修改tail,修改tail用CAS操作,CAS操作能把增加删除操作序列化
volatile防止编译器优化,指令乱序排列,保证内存中不存在一致性问题(保证释放监视器和获取监视器的两个线程之间的内存可见性,
这意味着对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入);
在这里插入图片描述
上图是等待某个条件满足的Thread队列的对象示意图;

对等待队列的操作(wait()、signal())必须要在排他模式下执行,也就是先获取锁,
获取或释放锁(lock() / unlock())关键是在获取或释放锁的状态(acquire(state) / release(state),修改state变量),
其它的锁的拥有者,锁的其它等待者都不重要,不是关键。
调用wait()的方法内先获取锁(lock(),当前线程加入到锁等待队列Node1),
wait()方法内把当前线程加入到条件等待队列(Node2),释放锁(release(state)),不断循环查询Node2是否被转移到了锁等待队列,
如果已在锁等待队列,结束park,重新获取锁(acquire(state),移走Node2),
调用wait()的方法操作业务数据,释放锁(unlock() -> release(state) -> unparkSuccessor(head) 移走Node1,唤醒后继等待者);
调用signal()的方法与调用wait()的方法类似;
signal()方法内会把条件等待队列中的Node转移到锁等待队列;
条件等待队列和锁等待队列共用同一把锁(state变量);
wait()、signal()主要是围绕着条件等待队列在进行操作;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值