admin 管理员组文章数量: 886992
容器——ConcurrentHashMap的底层实现原理
文章目录
- ConcurrentHashMap的底层实现原理
- 1、HashMap线程不安全
- 2、HashTable效率低下
- 3、ConcurrentHashMap的底层实现原理
- 3.1JDK1.7中的ConcurrentHashMap
- 3.2JDK1.8中的ConcurrentHashMap
ConcurrentHashMap的底层实现原理
1、HashMap线程不安全
HashMap是线程不安全的。
HashMap在并发执行put操作是会引起死循环,是因为多线程情况下在put()时进行resize()的扩容操作,执行transfer()的时候会导致HashMap的Entry链表形成环形数据结构,一旦形成环形数据结构,Entry的next节点永远不为空,就会产生死循环。
Map接口(代码模拟HashMap的底层实现)
HashMap的底层实现原理?(JDK1.7与JDK1.8源码分析对比)
2、HashTable效率低下
HashTable使用synchronized来保证线程的安全,但是在线程竞争激烈的情况下锁住整张表,效率非常低下。
当一个线程访问HashTable的同步方法,其他方法访问HashTable的同步方法时,会进入阻塞或者轮询状态。如果线程1使用put进行元素添加,线程2不但不能用put方法添加于元素同是也无法用get方法来获取元素,所以竞争越激烈效率越低。
HashMap和HashTable的区别?
3、ConcurrentHashMap的底层实现原理
3.1JDK1.7中的ConcurrentHashMap
JDK1.7中,ConcurrentHashMap采用的是锁分段技术。
HashTable容器在竞争激烈的并发环境下表现出效率低下的原因是所有访问HashTable的线程都必须竞争同一把锁,假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术。首先将数据分成一段一段地存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。
jdk1.7中采用Segment + HashEntry的方式进行实现,结构如下:
ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。Segment是一种可重入锁(ReentrantLock),在ConcurrentHashMap里扮演锁的角色;HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组。Segment的结构和HashMap类似,是一种数组和链表结构。一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素,每个Segment守护着一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得与它对应的Segment锁,如下图所示。
3.2JDK1.8中的ConcurrentHashMap
1.7中解决了并发问题,并且能支持 N 个 Segment 这么多次数的并发,但依然存在 HashMap 在 1.7 版本中的问题。那就是查询遍历链表效率太低。
1.8中放弃了Segment臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保证并发安全进行实现。锁住的是一个Node。
总体结构是数组+链表(红黑树),实现线程安全是通过Node+CAS+Synchronized实现的。
参考链接:分段锁的理解
本文标签: 容器ConcurrentHashMap的底层实现原理
版权声明:本文标题:容器——ConcurrentHashMap的底层实现原理 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1732354931h1534159.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论