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

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

ConcurrentHashMap源码分析。

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

ConcurrentHashMap源码分析。

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

ConcurrentHashMap源码分析。

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

ConcurrentHashMap源码分析。

总结下:

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

2.put分析

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

ConcurrentHashMap源码分析。

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

ConcurrentHashMap源码分析。

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

ConcurrentHashMap源码分析。

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

ConcurrentHashMap源码分析。

ConcurrentHashMap源码分析。

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

ConcurrentHashMap源码分析。

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

ConcurrentHashMap源码分析。

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

相关文章:

  • 2021-11-16
  • 2021-08-06
  • 2021-11-14
  • 2022-03-08
  • 2022-03-01
  • 2021-04-13
猜你喜欢
  • 2021-11-26
  • 2021-09-25
相关资源
相似解决方案