ConcurrentHashMap是如何保证线程安全的

news2024/11/25 19:45:04

ConcurrentHashMap是如何保证线程安全的

  • 定义和问题解决
  • JDK 1.7实现原理
  • JDK 1.8性能优化
  • 总结

定义和问题解决

ConcurrentHashMap相当于HashMap的多线程版本。

它的功能本质上和HashMap没有什么区别,因为HashMap在并发操作的时候会出现各种问题,比如:

  1. 死循环问题
  2. 数据覆盖等问题

而这些问题只要使用ConcurrentHashMap就能得到完美的解决。

ConcurrentHashMap是如何保证线程安全的。

JDK 1.7实现原理

在这里插入图片描述

JDK 1.7中ConcurrentHashMap的底层结构基本延续了HashMap的基本设计。它采用的是数组加链表的形式。

和HashMap不同的是ConcurrentHashMap中的数组被封分为大数组和小数组。大数组是Segment,小数组是HashEntry。大数组Segment可以理解为是一个数据库,而这个数据库又有很多张表,这个表就是HashEntry。

而每个HashEntry中又有很多条数据,这些数据采用的是链表结构

因为Segment本身是基于ReentrantLock重入锁的实现来加锁和释放锁的操作。这样的话就能够保证多线程同时访问ConcurrentHashMap的时候,同一时间只能有一个线程操作对应的节点。这样的话,保证了ConcurrentHashMap的线程安全。也就是说ConcurrentHashMap的线程安全是建立在Segment的加锁的基础上,所以我们称它为分段锁或者是分片锁

JDK 1.8性能优化

在JDK1.7中,ConcurrentHashMap虽然是线程安全的,但是它的底层实现是采用数组加链表的形式。所以在数据比较多的情况下,因为要遍历整个链表,这样的话会降低它的访问性能。

所以JDK1.8以后,就采用了数组加链表加红黑树的方式进行的优化。其具体实现如图所示:

在这里插入图片描述
当我们的链表长度大于8的时候,并且数组长度大于64的时候,链表就会升级为红黑树的结构。

JDK1.8中,ConcurrentHashMap保留了Segment的定义,但是者仅仅是为了保证序列化的时候的兼容性,不再有任何结构上的用途了。那在JDK1.8中,ConcurrentHashMap的源码又是如何实现的呢?

它主要是通过CAS加volatile或者是synchronized的方法来实现的,保证线程安全,我们可以从源码片段中看到添加元素的时候,首先会判断容器是否为空,如果容器为空,就会使用volatile加CAS来初始化。如果容器不为空,就会根据存储的元素计算该位置是否为空。如果根据存储元素的计算结果为空,就会利用CAS来设计该节点;如果根据存储元素的计算结果不为空,就会使用synchronized加锁来进行实现,然后去遍历桶中的数据,并且替换或新增节点到桶中。最后判断是否有必要转为红黑树。这样就保证了并发访问的线程安全。在这里插入图片描述

如果把上面的执行用一句话来归纳的话,就相当于ConcurrentHashMap通过对头节点加锁来保证线程安全,这样设计的好处是使得锁的粒度相比Segment来说更小了。发生hash冲突和加锁的频率也更低了,而在并发场景下操作性能也提高了。而且当数据量比较大的时候,查询性能也得到了进一步的提升。

总结

  1. JDK 1.7给Segment添加ReentrantLock锁来实现线程安全
    ConcurrentHashMap在JDK1.7中使用的是数组加链表结构,其中数组分为两大类,大数组是Segment,小数组是HashEntry。而加锁是通过Segment添加ReentrantLock重入锁来保证线程安全的。
  2. JDK 1.8通过CAS或者synchronized来实现线程安全
    ConcurrentHashMap在JDK1.8中使用的是数组加链表加红黑树的方式来实现。它是通过CAS或者synchronized来实现线程安全。并且也缩小了锁的粒度。查询性能也到了进一步的提升。

参考资料:【Java面试】京东二面,ConcurrentHashMap是如何保证线程安全?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/456587.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android混淆和反混淆

本篇来介绍下Android的混淆和反混淆,说起混淆,大家都会很自然地想到ProGuard,此外还有R8。事实上,AGP3.3之后,官方默认使用R8做代码优化、混淆和压缩。ProGuard和R8常常用于混淆最终的Android项目,增加项目…

Vue-router【VUE】

6. vue-router 6.1 相关理解 6.1.1 vue-router 的理解 路由就是一组key-value的对应关系。多个路由,需要经过路由器的管理vue是一个插件库,专门用来实现SPA应用。 6.1.2 对SPA应用的理解 单页 Web 应用(single page web application, SP…

C++基础阶段入门 (1)

1.C统一初始化: 初始化列表解决方案: //C语言的初始化方案 int main() {int a 10;int* ip nullptr;int ar[] { 12,23,34,45,56,67 }; } C 初始化:使用{ } int main(){//char ch a;char ch{ a };//int a 10;int a{ 10 };int b int(10);int x{ 10…

企业软文怎么写吸引人?教你几招

企业每年都要投放大量的商业软文到热门的内容平台上,也许现在你阅读的某篇文章,就是一篇企业软文。 真正厉害的软文在于你根本看不出来这是一条广告,从而让你心甘情愿的为某个产品掏腰包。企业软文到底怎么写才吸引人,接下来伯乐…

sfavsrv导致主机负载高

下午接客户电话,监控告警了,主机负载高,登录后top查看,确实比较的高 再次查看负载高的cpu发现是sfavsrv 吓了一跳,还以为中毒了,发给客户检查是否自行部署了第3方软件,确实第3方的,关…

如何将pdf图片文字转换成word 文字word图片怎么转换pdf

如今大家在工作中常常会运用到电脑来办公,电脑的运用大大提高了我们的工作效率,在带来机会的同时同样也带来了新挑战。 pdf图片怎么转换成word文档?PDF格式是一种常用的文档格式,它可以保持文档内容和格式的完整性,但是…

4月有8本SCIE期刊被剔除(附MDPI/Frontiers/Hindawi最新在检期刊)

2023年4月SCI、SSCI期刊目录更新 2023年4月18日,科睿唯安更新了WOS期刊目录,继上次3月WOS期刊目录剔除50本SCIE&SSCI期刊之后,此次4月更新又有8本SCIE期刊发生变动,其中有4本期刊被踢出SCIE数据库,4本期刊更改了名…

QMS-云质说质量 - 2 你真的知道什么是质量吗

云质QMS原创 转载请注明来源 作者:王洪石 引言 暴露的只是冰山一角 注:()中为ISO9000:2015 质量管理体系基础和术语的编号 一个组织的质量管理(3.3.4),可包括制定质量方针(3.5.9)和质量目标(3.7.2),以及通…

Web 攻防之业务安全:接口未授权访问/调用测试(敏感信息泄露)

Web 攻防之业务安全:接口未授权访问/调用测试 业务安全是指保护业务系统免受安全威胁的措施或手段。广义的业务安全应包括业务运行的软硬件平台(操作系统、数据库,中间件等)、业务系统自身(软件或设备)、业…

火车站闸机web3d数字展示平台全方位动态呈现设备细节

智能互联网时代,传统的图片、文字、视频等产品展示方式,因为缺少互动性,很难引起用户的兴趣,已经逐渐失去了宣传优势。 Web3D交互展示技术的出现,让众多品牌和企业找到了新的方向,线上产品展示不在枯燥无趣…

少儿编程 中国电子学会图形化编程等级考试Scratch编程一级真题解析(选择题)2023年3月

2023年3月scratch编程等级考试一级真题 选择题(共25题,每题2分,共50分) 1、下列说法不正确的是 A、可以从声音库中随机导入声音 B、可以录制自己的声音上传 C、可以修改声音的大小 D、不能修改声音的速度 答案:D…

计算机网络第1章(概述)

文章目录 1.1、计算机网络在信息时代的作用1.2、因特网概述1、网络、互连网(互联网)和因特网2、因特网发展的三个阶段3、因特网的标准化工作4、因特网的组成 1.3 三种交换方式1、电路交换(Circuit Switching)2、分组交换&#xff…

Composer使用教程

Composer使用教程 前言1.Composer 简介2. 下载与安装2.1 局部安装2.2 全局安装2.3 更新composer2.4查看composer2.5 安装composer镜像加速 3. composer的使用3.1初始化3.2安装第三方包 4. 自动加载器4.1 加载非 class 文件4.2 加载自己写 class 文件4.3 PSR-4 自动加载规范 5. …

【脱产二站上岸】上海交大819复习经验总结

笔者来自通信考研小马哥23上交819全程班学员 本科西南某985,成绩排名中下(面试被老师疯狂吐槽),一战本校,初试分数差10来分被刷。21年12月考完数学和专业课出来就知道考不上了,分数一出就下决心二战&#…

软件测试,想找一份20k以上的工作需要掌握哪些知识?

都知道IT行业是高薪人员的聚集地,但想要成为高薪程序员却并不容易。月薪20k是测试工程师的一个门槛,想要突破就必须掌握更多的技能。 因为程序员职业发展很快,即使是相同起点的人,经过几年的工作或学习,会迅速拉开极…

Python列表和字典前面为什么要加星号(**)?

人生苦短,我用python 今天来和大家一起学习一下为什么Python列表和字典前面会加星号()?** python 安装包资料:点击此处跳转文末名片获取 Python 中, 单星号*和双星号**除了作为“乘”和“幂”的数值运算符外&#xff…

【python的pdb调试简单了解一下?】

调试是程序开发过程中的重要环节,它可以帮助开发人员识别和解决程序中的错误和问题。Python 提供了一个内置的调试器 pdb(Python Debugger),可以帮助开发人员逐行分析代码、查看变量值、跟踪函数调用等。 入门 要使用 pdb 调试器…

Numpy从入门到精通——存读矩阵以及读取矩阵中的数据

这个专栏名为《Numpy从入门到精通》,顾名思义,是记录自己学习numpy的学习过程,也方便自己之后复盘!为深度学习的进一步学习奠定基础!希望能给大家带来帮助,爱睡觉的咋祝您生活愉快! 这一篇介绍《…

c#期末复习题重点难点题

2. (单选题, 9分)在.NET中,.NET Framework由( )组成。 A. FCL和CLR -开发库和运行环境B. ADO.NETASP.NET -数据操作和web框架C. CLS和CTS -语法规范和类型规范 即所有语言和语法规范 和 各语言间的类型互操作性规范D. Winform和ASP.NET…

2023前端面试上岸手册——JavaScript部分

目录 JavaScript 有哪些数据类型,它们的区别?数据类型检测的方式有哪些null 和undefined 区别如何获取安全的 undefined 值?Object.is() 与比较操作符 “两等” 、“三等” 的区别?什么是 JavaScript 中的包装类型?为什…