请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于ConcurrentHashMap写的同时读

老师,您好

图片描述

ConcurrentHashMap中的读没有任何锁,为什么可以在写的时候读却不出错呢?

正在回答

1回答

小伙伴的问题很好,它实现线程安全的原理是利用了volatile,保证了可见性,读取的时候是不需要加锁的,保证能读到最新的值,具体可以看这里:https://www.cnblogs.com/tiancai/p/13297793.html

关于volatile的原理,以及可见性、happens-before的内容, 可以看我的另一门课《Java并发核心知识体系精讲——完整清晰的并发知识网络+Java内存模型+高频面试题详解》https://coding.imooc.com/class/362.html

里面有详细介绍。

0 回复 有任何疑惑可以回复我~
  • 提问者 CoffeePlayer #1
    老师,我看过您的这门课,知道volatile的用法,它能保证可见性,还能防止重排序,但是它却不能保证原子性,我想问的是,假设线程A调用get首先拿到了头节点e,发现e不是想要查找的节点,就会用过链表往后查找,此时线程B添加了一个节点,正好变成了红黑树,改变了结构,这样线程A在读取的时候还是可能读取不到想要查找的节点
    回复 有任何疑惑可以回复我~ 2021-03-05 13:15:09
  • 悟空 回复 提问者 CoffeePlayer #2
    很好的问题,网上我没有搜到相关的内容,我自己的分析如下:你看一下treeifyBin的源码,是在构建完成了新的TreeNode之后,统一一下子替换到ConcurrentHashMap的根节点上,假设已经在通过链表往后找了,找到了一半被替换成红黑树了,那么也会继续执行往下找的代码:
    while ((e = e.next) != null) {
                    if (e.hash == h &&
                        ((ek = e.key) == key || (ek != null && key.equals(ek))))
                        return e.val;
                }
    这段代码对红黑树的节点TreeNode也是适用的,而且TreeNode也维护了next,所以也能继续找,找到想要的数据为止。
    下次再进来时,就会按照红黑树的方式去找了,也就是find方法。
    欢迎小伙伴提出自己的判断,我们一起交流。
    回复 有任何疑惑可以回复我~ 2021-03-05 15:15:41
  • 提问者 CoffeePlayer #3
    非常感谢!
    回复 有任何疑惑可以回复我~ 2021-03-06 14:20:23
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信