JavaSE基础-集合-ConcurrentHashMap

首先讲述一下为什么有ConcurrentHashMap诞生。我们都明白,ConcurrentHashMap是在HashMap的基础上诞生的,那么也就以为着它是在HashMap的基础上进行的优化。

hashMap作为map集合,key-vule的结构在开发中经常被使用,它的底层是hash表,默认大小16,2倍方式扩容以减少hash碰撞而形成链表结构导致影响查询效率。当然它是线程不安全的,在多线程、高并发的情况下就容易出现问题。那么根据常用但是线程又不安全的情况,对它进行优化。

ConcurrentHashMap:

ConcurrentHashMap在jdk发展中有一个巨大的变动,jdk1.7和jdk1.8。

jdk1.7

jdk1.7中ConcurrentHashMap设计加入了分段锁技术
jdk1.7及其以下的版本中,结构是用Segments数组 + HashEntry数组 + 链表实现

final Segment<K,V>[] segments;

Segment数组结构

  • Segment的结构和HashMap类似,是一种数组和链表结构, 一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素, 每个Segment守护者一个HashEntry数组里的元素,同时又是一个ReentrantLock(Segment继承了ReentrantLock)

HashEntry数组结构(桶)

  • 存储键值对数据

在这里插入图片描述

jdk1.7的ConcurrentHashMap内部结构:

分段锁技术就是将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问,能够实现真正的并发访问

ConcurrentHashMap定位一个元素的过程需要进行两次Hash操作。第一次Hash定位到Segment,第二次Hash定位到元素所在的链表的头部

jdk1.8

jdk1.8中ConcurrentHashMap结构做了进一步优化,结构变成了数组+链表+红黑树。由于jdk1.7中的结构存在效率不足的问题,所以对jdk1.7中的ConcurrentHashMap进行了提高效率的优化。同时也由cas + synchronized的方式保证数据的一致性,分段锁被去除,这就让结构变得更加简单。

在jdk1.8中Nod节点中value和next都用volatile修饰,保证并发的可见性。同时synchronized 只锁定当前链表或红⿊⼆叉树的⾸节点,这样只要 hash 不冲突,就不会产⽣并发,效率⼜提升 N 倍
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45937536/article/details/128814251