ConcurrentHashMap是如何保证线程安全的

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是如何保证线程安全?

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv1代码复现1:辅助功能实现

YOLOv1代码复现1:辅助功能实现 前言 ​ 在经历了Faster-RCNN代码解读的摧残后,下决心要搞点简单的,于是便有了本系列的博客。如果你苦于没有博客详细告诉你如何自己去实现YOLOv1,那么可以看看本系列的博客,也许可以帮助…

大屏开发需要知道哪些知识

大屏 大屏是什么呢?再我前几年刚接触这个词得时候很新颖,全名叫态势感知大屏,大屏得特点是炫酷、好看,给用户满满得科技感。 听一位前辈说当年再招标会上,再都用exel、word做界面图表文档得时候,有一家公司…

打包后dist包中app.**.js文件暴露大量接口信息,webpack-obfuscator对打包后的js代码混淆加密

问题描述 打包后dist包中app.**.js文件暴露大量接口信息,而webpack-obfuscator可以对打包后的js代码混淆加密 版本信息 webpack: 4.x.x node: 14.18.0 webpack4环境下使用webpack-obfuscator不能使用最新版本 我的下载版本是: npm install --save-de…

玩转ChatGPT:论文翻译润色

一、写在前面 首先还是让小Chat推销下自己: 嘿!你是否在写论文的过程中感到头疼,无从下手?你是否在担心自己的语言表达不够专业、不够流畅,影响了论文的质量?不要担心,ChatGPT的润色服务可以帮…

Redis 持久化八股文

目录 Redis的持久化机制 持久化方式对比 RDB RDB 持久化 RDB 的优缺点 优点 缺点 RDB 快照时运行修改数据吗 RDB 快照时修改数据过程 写时复制技术 RDB 的执行频率 增量快照 AOF 如何开启AOF AOF 为什么要采用后写日志呢? 后写日志的弊端 AOF 的优…

pdf转成word | ppt | jpg图片,免费一键转换教程

我不允许真的还有人不知道如何免费将pdf转成 ppt、word 或者 jpg图片! 职场小伙伴是不是会经常遇到pdf怎么转成word,pdf怎么转成word,pdf怎么jpg图片等问题?别再为pdf转化格式难、而且还要付费而发愁了!这份pdf免费一…

Python OpenCV3 计算机视觉秘籍:6~9

原文:OpenCV 3 Computer Vision with Python Cookbook 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 计算机视觉 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 当别人说你没有底线的时候&…

IDAPython入门基础语法

文章目录 参考文章IDAPython简介常用函数获取界面地址的函数数值获取函数数值判断函数patch操作函数去除花指令实例 参考文章 IDAPython入门教程 基于IDA7.5_Python3 第一讲 简介与地址获取 IDAPython简介 IDAPython拥有强大的功能,在使用IDA分析程序时非常有用,可以简化许多…

QT 插件通信接口调用 CTK开发(四)

CTK 为支持生物医学图像计算的公共开发包,其全称为 Common Toolkit。为医学成像提供一组统一的基本功能;促进代码和数据的交互及结合;避免重复开发;在工具包(医学成像)范围内不断扩展到新任务,而不会增加现有任务的负担;整合并适应成功的解决方案。 本专栏文章较为全面…

信息安全复习三:古典密码之设计好的密码算法

一.章节梗概 讨论以下算法,理解怎么设计好的密码算法的关键问题 1.Caesar cipher 2.单字母表密码 3.Playfairmima 4.维吉尼亚密码 5.自动生成密码 二.Caesar cipher 2.1 穷举攻击 穷举攻击定义:尝试所有密钥直到有一个合法密钥能够把密文还原成明文&…

Docker私有仓库Harbor搭建及使用

文章目录 一、Harbor简介二、Harbor仓库部署三、Harbor仓库使用 一、Harbor简介 官网地址:https://github.com/goharbor/harbor Docker容器应用的开发和运行离不开可靠的镜像管理,虽然Docker官方也提供了公共的镜像仓库,但是从安全和效率等…

如何在Web上实现激光点云数据在线浏览和展示?

无人机激光雷达测量是一项综合性较强的应用系统,具有数据精度高、层次细节丰富、全天候作业等优势,能够精确测量三维现实世界,为各个行业提供了丰富有效的数据信息。但无人机激光雷达测量产生的点云数据需要占用大量的存储空间,甚…

SpringSecurity之权限模块设计

目录 前言 实现思路 代码结构 使用说明 前言 前面我们了解了关于微服务权限设计方案以及J W T的相关介绍,今天我们来聊一下,如何避免自己重复的写相同的代码,一次代码实现,即可完美复制到任何项目中实现权限相关的功能。 实现…

RK3568平台开发系列讲解(驱动基础篇)SMP(Symmetrical Multi-Processing)

🚀返回专栏总目录 文章目录 一、linux SMP 和 AMP二、linux SMP的启动流程三、CPU的描述:cpumask四、CPU之间的关系沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍 SMP(Symmetrical Multi-Processing)。 一、linux SMP 和 AMP 目前支持多核处理器的实时操…

CxImage学习使用1:环境搭建

目录 前言 一、CxImage相关介绍 二、编译源码 三、将CxImage使用到自己的工程中 前言 CxImage是一个可以用于MFC 的C图像处理类库类,它可以打开,保存,显示,转换各种常见格式的图像文件,比如BMP, JPEG, GIF, PNG, TI…

300元的蓝牙耳机什么牌子好?300内无线蓝牙耳机推荐

感受过无线的自在舒适后,越来越多的小伙伴爱上了蓝牙耳机白天出街更潇洒,目前市面上蓝牙耳机琳琅满目可选择性较多价格从几十、几百元到数千元不等然而蓝牙耳机的安全性、舒适性如何?连接稳吗?下面整理了几款300元价位的耳机分享给…

【CSDN周赛】第46期题解

👨‍💻个人主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 本文章收录于专栏 【CSDN周赛】 本篇文章目录 🌏一、吃吃吃🌸题目描述🌸题解 🌏二、n …

Java核心技术 卷1-总结-12

Java核心技术 卷1-总结-12 具体的集合链表数组列表 具体的集合 下表中除了以 Map结尾的类之外, 其他类都实现了 Collection 接口,而以 Map结尾的类实现了 Map 接口。 集合类型描述ArrayList一种可以动态增长和缩减的索引序列LinkedList一种可以在任何位…

MySQL高级篇——索引的创建与设计原则

导航: 【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线牛客面试题 目录 一、索引的分类与使用 1.1 索引的分类 1.1.1. 普通索引 1.1.2. 唯一性索引 1.1.3. 主键索引(唯一非空) 1.1.4…