ConcurrentHashMap源码分析。

本文介绍了ConcurrentHashMap的数据结构,它类似HashMap,内部维护Segment数组,Segment继承自ReentrantLock,还维护HashEntry数组和链表。在put数据时,先计算hash值获取对应segment,尝试获取锁,若失败则扫描重试,获锁后设置值,最后释放锁,采用非全局的分段锁机制。

1.数据结构(数组+链表)

  同hashmap类似,首先内部维护了一个Segment<K,V>数组。

这个Segment比较有特色,它继承自ReentrantLock

同时在Segment中也维护着一个HashEntry<K,V> table,这个跟HashMap中维护Entry<K,V>[]比较相像了。

再看下HashEntry的结构,发现它也是个链表结构,跟HashMap中的Entry<K,V>是不是几乎一模一样。

总结下:

ConcurrentHashMap的数据结构:segment[] -- HashEntry[] -- HashEntry链表;HashMap的数据结构:Entry<K,V> -- Entry链表。

2.put分析

  put数据时,先计算hash值,再通过下图红框部分获得对应segment,执行s.put。

  s.put时,会先尝试获取锁(因为Segment集成自ReentrantLock,所以可以直接用tryLock()方法),如果成功获得锁,则HashEntry<K,V>为null,否则持续扫描(超过最大默认最大次数64停止)获得锁。

cpu处理器核数大于1则最大扫描重试次数为64,否则为1。

下面看看为put获取锁操作,注意下图红色部分,每次在做if判断前都先进行了自增,当重试次数超过最大次数后,会将当前线程变成不可用状态,直到获取到锁(相当于阻塞)。

获得锁之后开始进行put设置值,这部分跟HashMap类似。

到最后返回值,并释放锁。

concurrent这种非全局锁(又称分段锁)是不是挺有意思的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kenick

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值