码迷,mamicode.com
首页 > 其他好文 > 详细

ConcurrentHashMap

时间:2020-03-14 12:30:45      阅读:42      评论:0      收藏:0      [点我收藏+]

标签:节点   size   多个   结果   容量   概念   大量   family   需要   

参考:https://juejin.im/post/5ca89afa5188257e1d4576ff

jdk7Segment数组结构和HashEntry数组结构组成。HashEntry则用于存储键值对数据,Segment是一种可重入锁ReentrantLockSegment的结构和HashMap类似,是一种数组和链表结构,一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素, 每个Segment守护着一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。多个线程可以同时访问不同分段锁上的桶,从而使其并发度更高(并发度就是 Segment 的个数,默认的并发级别为 16,也就是说默认创建 16 Segment)。每个 Segment 维护了一个 count 变量来统计该 Segment 中的键值对个数。在执行 size 操作时先尝试不加锁,如果连续两次不加锁操作得到的结果一致,那么可以认为这个结果是正确的。尝试次数用RETRIES_BEFORE_LOCK 定义,该值为 2retries 初始值为 -1,因此尝试次数为 3。如果尝试的次数超过 3 次,就需要对每个 Segment 加锁。

ConcurrentHashMap不会增加Segment的数量,而只会增加Segment中链表数组的容量大小,这样的好处是扩容过程不需要对整个ConcurrentHashMaprehash,而只需要对Segment里面的元素做一次rehash就可以了。

modCount 操作次数 只增不减

remove 将定位之后的所有entry克隆并拼回前面去

get 流程:

根据key定位hash桶,通过tabAtvolatile读,获取hash桶的头结点。

通过头结点Nodevolatile属性next,遍历Node链表

找到目标node后,读取Nodevolatile属性val

 

jdk8 synchronized+CAS+HashEntry+红黑树

1.数据结构:取消了Segment分段锁的数据结构,取而代之的是数组+链表+红黑树的结构。

2.保证线程安全机制:JDK1.7采用segment的分段锁机制实现线程安全,JDK1.8采用CAS+Synchronized保证线程安全。

3.锁的粒度:原来是对需要进行数据操作的Segment加锁,现调整为对每个数组元素加锁(Node)。

4.链表转化为红黑树:定位结点的hash算法简化会带来弊端,Hash冲突加剧,因此在链表节点数量大于8时,会将链表转化为红黑树进行存储。

5.查询时间复杂度:从原来的遍历链表O(n),变成遍历红黑树O(logN)

 

对比总结

ConcurrentHashMap只是增加了同步的操作来控制并发,从JDK1.7版本的ReentrantLock+Segment+HashEntry,到JDK1.8版本中synchronized+CAS+HashEntry+红黑树,相对而言,总结如下思考

1.JDK1.8的实现降低锁的粒度,JDK1.7版本锁的粒度是基于Segment的,包含多个HashEntry,而JDK1.8锁的粒度就是HashEntry(首节点)

2.JDK1.8版本的数据结构变得更加简单,使得操作也更加清晰流畅,因为已经使用synchronized来进行同步,所以不需要分段锁的概念,也就不需要Segment这种数据结构了,由于粒度的降低,实现的复杂度也增加了

3.JDK1.8使用红黑树来优化链表,基于长度很长的链表的遍历是一个很漫长的过程,而红黑树的遍历效率是很快的,代替一定阈值的链表,这样形成一个最佳拍档

4.JDK1.8为什么使用内置锁synchronized来代替重入锁ReentrantLock,我觉得有以下几点.因为粒度降低了,在相对而言的低粒度加锁方式,synchronized并不比ReentrantLock差,在粗粒度加锁中ReentrantLock可能通过Condition来控制各个低粒度的边界,更加的灵活,而在低粒度中,Condition的优势就没有了.JVM的开发团队从来都没有放弃synchronized,而且基于JVMsynchronized优化空间更大,使用内嵌的关键字比使用API更加自然.在大量的数据操作下,对于JVM的内存压力,基于APIReentrantLock会开销更多的内存,虽然不是瓶颈,但是也是一个选择依据

 

ConcurrentHashMap

标签:节点   size   多个   结果   容量   概念   大量   family   需要   

原文地址:https://www.cnblogs.com/scChen/p/12491356.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!