采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
老师,您好
ConcurrentHashMap中的读没有任何锁,为什么可以在写的时候读却不出错呢?
小伙伴的问题很好,它实现线程安全的原理是利用了volatile,保证了可见性,读取的时候是不需要加锁的,保证能读到最新的值,具体可以看这里:https://www.cnblogs.com/tiancai/p/13297793.html
关于volatile的原理,以及可见性、happens-before的内容, 可以看我的另一门课《Java并发核心知识体系精讲——完整清晰的并发知识网络+Java内存模型+高频面试题详解》https://coding.imooc.com/class/362.html
里面有详细介绍。
老师,我看过您的这门课,知道volatile的用法,它能保证可见性,还能防止重排序,但是它却不能保证原子性,我想问的是,假设线程A调用get首先拿到了头节点e,发现e不是想要查找的节点,就会用过链表往后查找,此时线程B添加了一个节点,正好变成了红黑树,改变了结构,这样线程A在读取的时候还是可能读取不到想要查找的节点
很好的问题,网上我没有搜到相关的内容,我自己的分析如下:你看一下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方法。 欢迎小伙伴提出自己的判断,我们一起交流。
非常感谢!
登录后可查看更多问答,登录/注册
JUC全方位讲解,构建并发工具类知识体系
1.0k 11
1.4k 10
1.1k 10
1.0k 10
1.5k 9