浅析ConcurrentHashMap

一、什么是ConcurrentHashMap

ConcurrentHashMapHashMap一样,是一个存放键值对的容器。使用hash算法来获取值的地址,因此时间复杂度是O(1)。查询非常快。
同时,ConcurrentHashMap是线程安全的HashMap。专门用于多线程环境。

在这里插入图片描述

1.ConcurrentHashMap的整体架构

在这里插入图片描述

上图是ConcurrentHashMap在jdk1.8中的存储结构,它是由数组,单向链表和红黑树来构成的,当我们去初始化一个ConcurrentHashMap实例的时候,默认会初始化一个长度等于16的数组,由于ConcurrentHashMap他的核心仍然是hash表,所以必然会存在hash冲突的问题,所以ConcurrentHashMap采用链式寻址的方式来解决hash表的冲突,当hash冲突比较多的时候,会造成链表长度较长的问题,所以这种情况下会使得ConcurrentHashMap中的一个数组元素的查询复杂度会增加,所以在jdk1.8中引入了红黑树这种机制,当数组长度大于64并且链表的长度大于等于8时,单向链表就会转化成红黑树,另外随着ConcurrentHashMap的动态扩容,一旦链表的长度小于8,红黑树会退化成单向链表,

2.ConcurrentHashMap的基本功能

ConcurrentHashMap本质上是一个hashmap,因此功能和hashmap是一样的,但是ConcurrentHashMap在hashmap的基础上,提供了并发安全的一个实现,并发安全的一个主要实现,主要是通过对node节点去加锁来保证数据更新的安全性,下图所示
在这里插入图片描述

3.ConcurrentHashMap在性能方面做的优化

如何在并发性能和数据安全性之间做好平衡,在很多地方都有类似的设计,比如cpu的三级缓存,mysql的buffer——pool,synchronized的锁升级等等
在这里插入图片描述

ConcurrentHashMap也做了类似的优化,主要体现在几个方面,
第一个:在jdk1.8中,ConcurrentHashMap他的锁的粒度是数组中的某一个节点,而在jdk1.7里面,它锁定的是segment,锁的范围要更大,所以性能上会更低

第二个:引入红黑树这样一个机制,去降低了数据查询的时间复杂度,红黑树的时间复杂度是o(logn

第三个:看下图

在这里插入图片描述

当数组的长度不够的时候,ConcurrentHashMap它需要对数组进行扩容,而在扩容的时间上,ConcurrentHashMap引入了多线程并发扩容的一个实现,简单来说就是多个线程对原始数组进行分片,分片之后,每个线程去负责一个分片的数据迁移,从而去整体的提升了扩容过程中的数据迁移的一个效率,

第四:ConcurrentHashMap他有一个size()方法来获取总的元素个数,而在多线程并发场景中,在保证原子性的前提下去实现元素个数的累加,性能是非常低的,所以ConcurrentHashMap在这个方面做了两个点的优化,

在这里插入图片描述

第一个点是当线程竞争不激烈的时候,直接采用cas的方式来实现元素个数的一个原子递增,
第二个:如果线程竞争比较激烈的情况下,使用一个数组来维护元素个数,如果要增加总的元素个数的时候,直接从数组中随机选择一个,再通过cas算法来实现原子递增,它的核心思想是引入了数组来实现对并发更新的一个负载

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值