大家好,我是阿轩 。
每当我们谈到并发包的时候,脑海中的第一印象就是ConcurentHashMap类,的确,这个类的很多并发设计思想非常值得我们借鉴,阿轩也趁着周末想仔细研究一下,但是每当遇到问题想求助浏览器的时候,发现很多文章都是 ctrl+c ctrl+v,很多细节压根没提,无奈,只能静下心来,自己研究了

文章插图
这篇文章主要是对核心方法 put get 中的细节进行一个详细的剖析,版本是 JDK1.8.0_241,至于 7 和 8 的区别,网上已经有很多文章了,本篇就不再继续啰嗦了,话不多说,我们开始
putput 源码比较长,我们先看上半部分

文章插图
第一个 if 判断集合是否为空,为空进行初始化

文章插图
这里介绍一下 sizeCtl 这个变量
private transient volatile int sizeCtl;他是被 volatile 修饰的,具有线程可见性,当初始化和扩容时是负数,其他时候是正数刚进入循环的时候,sizeCtl 是正数,所以会走到 ②,这里会使用 CAS 进行无锁赋值,CAS 失败的线程下一个循环来到 ①,让出 CPU 时间片 。
CAS 成功的线程会进行数组的初始化,当我们实例化 ConcurrentHashMap 的时候,如果传入了初始容量大小,那么会对传入的这个参数进行一系列的位运算,最终得到一个 2 的幂次方的值,如果没有传入初始容量,那么 siteCtl 就等于默认值 0,所以如果传入了初始容量,n 就等于计算后的值,没传就等于默认值 DEFAULT_CAPACITY
private static final int DEFAULT_CAPACITY = 16;所以 ConcurrentHashMap 的默认初始化容量是 16,和 HashMap 一样,初始化数组之后会将 sizeCtl 设置为(容量 x0.75) 大小,作为下一次扩容的阈值 。其他自旋等待的线程发现 table!=null 后跳出循环回到 putVal 方法,此时来到判断 ②,通过 tabAt 方法求出目标索引位的值,(n - 1) & hash等同于hash%n,也就是对容量大小进行取余,计算出目标所在的索引位 i
static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);}这里通过 Unsafe 的 getObjectVolatile 方法进行取值,getObjectVolatile 具有 valotile 的语义,可以获取 i 索引处的最新值,如果值为 null,新建一个 Node 对象,然后通过 CAS 进行赋值static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,Node<K,V> c, Node<K,V> v) {return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);}如果 CAS 赋值成功,跳出循环,赋值失败,进入下一次循环,来到 ③,判断目标节点的 hash 值是否等于 MOVED,也就是-1,static final int MOVED = -1;如果等于则帮助扩容,扩容后面再细讲,我们来看最后一个判断如果目标索引位的值既不为 null,也不在扩容,那么就直接加锁开始判断节点的 key 是否相等 。
这里可能有读者会想,前面赋值的时候使用的是 CAS,那么这里可不可以也使用 CAS 呢
阿轩仔细思考了一下,其实这里是没办法用 CAS 的

文章插图
原因有 3 点
- 如果此时有大量的线程进行 put 操作,而这些操作的 key 都是相等的,如果此时节点的值为 null,那么通过 CAS 操作后,节点的值就不为 null 了,下一次循环就不会再进入这个 if 判断,但是如果该节点是有值的,那么只有一个线程可以通过 CAS 操作成功,其他线程下一次循环的时候还是会进入这个 if 判断再次尝试进行 CAS 操作,并发很高的时候会造成很多无用的自旋操作,而且 JDK8 的 synchronized 经过优化之后性能已经很好了,所以不如直接进行 synchronized 加锁操作,反而来的更快
- 陆游临安春雨初霁赏析及感悟 临安春雨初霁陆游赏析
- 不足5㎡的卫生间,也有很多需要“操心的事”,建议大家收藏!
- 孕产妇孕期保健 孕妇保健app
- game游戏中心官方 在线游戏网站
- 核舟记翻译文言文 核舟记翻译最简短
- 刀锋意志 手游刀锋意志出装
- 现代养殖业最赚钱行业 哪种养殖业最赚钱
- 火炬之光1技能树 火炬之光技能搭配
- 皇帝成长计划游戏 皇帝成长计划测试版
- 阿里巴巴国际站好做吗? 阿里巴巴国际站怎么做好
特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
