蚂蚁花呗:阿里巴巴面试:Java 集合知识点(附图文解析)( 七 )
Segment 类Segment 类继承于 ReentrantLock 类 , 从而使得 Segment 对象能充当可重入锁的角色 。 一个 Segment 就是一个子哈希表 , Segment 里维护了一个 HashEntry 数组 , 并发环境下 , 对于不同 Segment 的数据进行操作是不用考虑锁竞争的 。
从源码可以看到 , Segment 内部类和我们上边看到的 HashMap 很相似 。 也有负载因子 , 阈值等各种属性 。
HashEntry 类HashEntry 是目前我们最小的逻辑处理单元 。 一个ConcurrentHashMap 维护一个 Segment 数组 , 一个Segment维护一个 HashEntry 数组 。
ConcurrentHashMap 类默认的情况下 , 每个ConcurrentHashMap类会创建16个并发的 segment , 每个 segment 里面包含多个 Hash表 , 每个 Hash 链都是由 HashEntry 节点组成的 。
put() 方法
- 定位segment并确保定位的Segment已初始化
- 调用 Segment的 put 方法 。
get() 方法get方法无需加锁 , 由于其中涉及到的共享变量都使用volatile修饰 , volatile可以保证内存可见性 , 所以不会读取到过期数据
JDK1.8 实现
ConcurrentHashMap 在 JDK8 中进行了巨大改动 , 光是代码量就从1000多行增加到6000行!1.8摒弃了Segment(锁段)的概念 , 采用了 CAS + synchronized 来保证并发的安全性 。
可以看到 , 和HashMap 1.8的数据结构很像 。 底层数据结构改变为采用数组+链表+红黑树的数据形式 。
和 HashMap1.8 相同的一些地方
- 底层数据结构一致
- HashMap初始化是在第一次put元素的时候进行的 , 而不是init
- HashMap的底层数组长度总是为2的整次幂
- 默认树化的阈值为 8 , 而链表化的阈值为 6
- hash算法也很类似 , 但多了一步& HASH_BITS , 该步是为了消除最高位上的负符号 , hash的负在ConcurrentHashMap中有特殊意义表示在扩容或者是树节点
一些关键属性
put() 方法
- 首先会判断 key、value是否为空 , 如果为空就抛异常!
- spread()方法获取hash , 减小hash冲突
- 判断是否初始化table数组 , 没有的话调用initTable()方法进行初始化
- 判断是否能直接将新值插入到table数组中
- 判断当前是否在扩容 , MOVED为-1说明当前ConcurrentHashMap正在进行扩容操作 , 正在扩容的话就进行协助扩容
- 当table[i
为链表的头结点 , 在链表中插入新值 , 通过synchronized (f)的方式进行加锁以实现线程安全性 。
- 在链表中如果找到了与待插入的键值对的key相同的节点 , 就直接覆盖
- 如果没有找到的话 , 就直接将待插入的键值对追加到链表的末尾
- 当table[i
为红黑树的根节点 , 在红黑树中插入新值/覆盖旧值
- 根据当前节点个数进行调整 , 否需要转换成红黑树(个数大于等于8 , 就会调用treeifyBin方法将tabel[i
第i个散列桶拉链转换成红黑树)
- 对当前容量大小进行检查 , 如果超过了临界值(实际大小*加载因子)就进行扩容
我们可以发现 JDK8 中的实现也是锁分离的思想 , 只是锁住的是一个 Node , 而不是 JDK7 中的 Segment , 而锁住Node 之前的操作是无锁的并且也是线程安全的 , 建立在原子操作上 。
get() 方法get 方法无需加锁 , 由于其中涉及到的共享变量都使用 volatile 修饰 , volatile 可以保证内存可见性 , 所以不会读取到过期数据
推荐阅读
- 阿里巴巴|反击开始!马云、马化腾、任正非相继出手,网友炸锅:干得漂亮
- 阿里巴巴|电商风云再起?拼多多来势汹汹,疯狂攻击阿里“命门”!
- 数码科技大爆炸|支付宝再次上线新功能!月光族有福气了:花呗支付可免首付无利息
- 阿里巴巴|好戏还在后面!英国尝到“苦头”,美国表态:不关我的事
- 蚂蚁花呗|支付宝再次上线新功能! \月光族\有福气了: 花呗支付可免首付无利息
- 蚂蚁花呗|你可能一直在错误的使用支付宝和蚂蚁花呗
- 产业气象站|会对车贷、房贷产生影响?花呗客服回应,花呗部分用户接入央行征信
- 阿里巴巴|你觉得华为与阿里巴巴,谁掌握的世界性先进技术比更多?
- 蚂蚁花呗|支付宝花呗“服务升级”,这些行为将上报征信!
- 阿里巴巴|马云不再沉默,面对印度的施压,阿里直接遣散印度公司员工
