ConcurrentHashMap实现原理

本文对比分析了JDK1.7和1.8中ConcurrentHashMap的实现原理,包括其线程安全机制、数据结构(如数组、链表、红黑树)、分段锁和CAS+synchronized的使用,以及与HashTable的效率对比。

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

我结合上一篇的HashMap再来复习一下ConcurrentHashMap
ConcurrentHashMap和HashMap相比较最大的不同是线程安全
至于为什么线程安全在JDK1.7和Jdk1.8是不一样的
我们来看看1.7版本

1.它的底层数据结构还是数组加上链表 ,HashEntry为链表的结点

2.它主要采用了segment分段锁技术,在多线程并发操作的时候。对同一个segment进行同步加锁,保证数据的安全。这样就可以基于不同的segment进行并发写操作。这样就提升了效率我们通过和HashTable相比较来更深刻的理解为什么这样更有效率,以及为什么ConcurrentHashMap的效率比同是多线程的HashTable更高,因为HashTable将整个put/get,操作都锁上了,这就导致锁上了整个HashTable对象,这样的话效率就很低,比如 在 有些不同的indx值进行写操作,ConcurrentHashMap可以可能进行并行或者并发来处理,效率更高,而HashTable只能同步互斥来处理,总的来说我们细化了锁,在等下我们提到jdk1.8版本的时候我还会再说说 ,segment的缺点,以及其他的补充。

3.同步的实现方式也就是我们上面提到的分段锁,是继承了Reentrant锁机制,(segment继承自ReentrantLock)。具体来说对于同一个segment的操作是ReentrantLock.lock()/unlock()进行线程间的同步。

4.和HashMap一样。同样存在hash冲突,链表查询效率低的问题

我们来看看1.8

**1.**底层的数据结构和1.8版本的HashMap一样为 数组+链表+红黑树.

**2.**支持多线程的并发操作。实现原理是:CAS+synchronized保证并更新

**3.**put方法存放元素时,通过key对象的hashcode计算数组的索引,如果没有Node,
则使用CAS尝试插入元素,失败则无条件自旋直到插入成功;如果存在Node,则使用synchronized锁住该元素(链表/红黑树的头节点),在执行插入操作

1.7和1.8的共同点

1.键,值迭代器为弱一致性迭代器 fail -safe迭代器 ,创建迭代器之后可以对元素进行更新,

2.读操作没有加锁,value是volatie修饰的,保证了可见性,所以是安全的

3.读写分离可以提高效率:多线程对不通过的Node/Segment的插入/删除可以并发,并行执行,读操作都是无锁操作,可以并发并行执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值