面试题:ConcurrentHashMap 1.7和1.8的区别

本文记录了ConcurrentHashMap 1.7和1.8的区别,包括整体结构、put、get、resize、size等方面。1.8移除了Segment,锁粒度更小,支持并发扩容等。还提到面试官关于短时间大量数据插入ConcurrentHashMap以提高插入效率的问题,作者给出两点思路并求更多方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

面试官问到这个我觉得送分了,觉得自己答的挺好,面完看看其实发现还是有一些没答全,写个帖子记录下。

ConcurrentHashMap 1.7和1.8的区别

1、整体结构

1.7:Segment + HashEntry + Unsafe

1.8: 移除Segment,使锁的粒度更小,Synchronized + CAS + Node + Unsafe

2、put()

1.7:先定位Segment,再定位桶,put全程加锁,没有获取锁的线程提前找桶的位置,并最多自旋64次获取锁,超过则挂起。

1.8:由于移除了Segment,类似HashMap,可以直接定位到桶,拿到first节点后进行判断,1、为空则CAS插入;2、为-1则说明在扩容,则跟着一起扩容;3、else则加锁put(类似1.7)

3、get()

基本类似,由于value声明为volatile,保证了修改的可见性,因此不需要加锁。

4、resize()

1.7:跟HashMap步骤一样,只不过是搬到单线程中执行,避免了HashMap在1.7中扩容时死循环的问题,保证线程安全。

1.8:支持并发扩容,HashMap扩容在1.8中由头插改为尾插(为了避免死循环问题),ConcurrentHashmap也是,迁移也是从尾部开始,扩容前在桶的头部放置一个hash值为-1的节点,这样别的线程访问时就能判断是否该桶已经被其他线程处理过了。

5、size()

1.7:很经典的思路:计算两次,如果不变则返回计算结果,若不一致,则锁住所有的Segment求和。

1.8:用baseCount来存储当前的节点个数,这就设计到baseCount并发环境下修改的问题(说实话我没看懂-_-!)。

总结

面试官还提了一个很有意思的问题,背景是这样,如何在很短的时间内将大量数据插入到ConcurrentHashMap,换句话说,就是提高ConcurrentHashMap的插入效率,我大概说了尽量散列均匀和避免加锁两个点,但是面试官还在问还有什么思路没?如果有人看到又有什么方案的话请留言!万分感激!

评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值