ConcurrentHashMap实现原理

ConcurrentHashMap实现原理
在JDK1.7中:
ConcurrentHashMap是通过Segment数组+HashEntry数组+单链表的结构进行存储数据。Segment数组中存放的是HashEntry数组的首地址,HashEntry中存放的是一个单链表(首节点地址)。
put():我们通过put()方法向ConcurrentHashMap中存放数据,首先会通过key计算出hash值,通过hash值定位到相应的Segment,然后再将这个Segment加锁,判断是否需要扩容,需要则扩容,然后根据这个Segment所对应的HashEntry索引最大值(数组长度-1)和hash值按位与(&)的结果定位到相应的HashEntry,然后遍历这个单链表,如果有重复值,则覆盖,并将旧值赋给变量oldValue,如果没有重复值,则在链表头插入,并将null赋值给oldValue,最后返回oldValue,并解锁,完成对数据的添加。
get():我们通过get()方法获取ConcurrentHashMap的值,首先通过key获取hash值,定位到相应的Segment,然后用和put()方法相同的方式定位到相应的HashEntry,然后遍历单链表,如果有元素的key和所要获取的key的hash值相等并且key的equals比较结果为真,则将该元素的value赋值给变量v,若v不为null则返回,否则返回一个加锁读直接获取该元素的值,如果遍历要还没有找到则返回为null。
在JDK1.8中,
ConcurrentHashMap采用Node数组+链表+红黑树的结构存储元素。
put():首先利用key计算hash值,根据hash值定位到相应的Node,如果Node数组还未初始化则先初始化,然后判断是否正在扩容,如果正在扩容,则返回扩容后的数组,然后将该Node加锁,如果Node中存放的是链表结构,则遍历链表,有重复值则覆盖,没有则在链表头插入,返回oldValue,如果是红黑树结构,按照红黑树的插入方式插入,如果插入后节点个数大于等于8,则将其转换为红黑树,最后计数值加一(可能引发扩容)。
get():和HashMap的get()方法类似,先根据key计算出来的hash值定位Node,然后遍历链表或者红黑树,找到则返回,未找到则返回为null。
JDK1.7和JDK1.8中ConcurrentHashMap的实现原理,1.7中是将整个HashEntry加锁,而1.8是将链表或者红黑树加锁,进一步减少并发冲突,而且采用链表+红黑树的结构存储数据使得数据在整个数组中分布很均匀,提高了查询效率,提高了性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值