ConcurrentHashMap 为什么是线程安全的?

1、典型回答

ConcurrentHashMap 在不同JDK 版本中,保证线程安全的手段是不同的,它主要分为以下两种情况:

  1. JDK 1.7 之前(包含JDK 1.7),ConcurrentHashMap 主要是通过分段锁 (Segment Lock) 来保证线程安全的。
  2. 而在JDK 1.8 之后(包含JDK 1.8) ,使用了粒度更小锁,通过在数组的头节点加锁来保证线程安全的,并且加锁的手段也进行了优化,它使用的是 CAS + volatile 或 synchronized 来保证线程安全的。

2、全面剖析

concurrentHashMap 在早期版本中(JDK 1.7 之前,包含JDK 1.7)是通过悲观锁 Lock 添加分段锁来保证线程安全的,而到了之后版本中,是通过粒度更小的在数组头节点加锁(悲观锁 synchronized 或者是乐观锁CAS+volatile)的方式来保证线程安全的

那么问题来了,什么是分段锁? 请参考:什么是分段锁?-CSDN博客

分段锁的实现如下图所示:

高版本头节点加锁示意图如下:

3、知识扩展

什么是悲观锁和乐观锁? 它们有什么区别?

悲观锁和乐观锁是并发编程中常用的两种锁机制(或者说两种锁策略或者是两种实现锁的思想)
它们的区别如下:

  1. 悲观锁(Pessimistic Locking):悲观锁假设会发生竞争,因此在访问共享资源前会获取锁,以防止其他线程对该资源的修改。悲观锁在操作期间会将共享资源锁定,其他线程无法操作,直到锁被释放。!典型的悲观锁实现包括 synchronized 关键字和 ReentrantLock。
  2. 乐观锁(Optimistic Locking):乐观锁假设不会发生竞争,因此在访问共享资源时不会加锁,而是在更新资源时检查是否有其他线程同时更新,并通过版本号等方式进行验证。如果验证通过,则更新资源,否则重新尝试。乐观锁适用于并发冲突相对较少的情况,能够提高并发性能。典型的乐观锁实现包括 CAS(Compare andSwap) 操作和版本号机制。

它们的区别主要体现在以下几点:

  • 加锁机制:悲观锁在访问共享资源前会获取锁,而乐观锁在访问共享资源时不会加锁
  • 锁状态:悲观锁将共享资源锁定,其他线程无法操作,而乐观锁不会锁定资源,允许其他线程同时访问。
  • 并发性能:乐观锁适用于并发冲突较少的场景,可以提供更好的并发性能,而悲观锁则适用于竞争较激烈的场景,保证数据的一致性和安全性。

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

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

相关文章

【数据结构和算法初阶(C语言)】二叉树的链式结构--前、中、后序遍历实现详解,节点数目计算及oj题目详解---二叉树学习日记③

1.二叉树的链式存储 二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是 链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所 在的链结点的存…

Qt——2D画图

基础画图函数 矩形 painter.drawRect(50,50,200,100); 圆角矩形 painter.drawRoundRect(50,50,200,200,50,50); xRadius和yRadius分别以矩形宽度和高度的一半的百分比指定,并且应该在0.0到100.0的范围内 弧线 painter.drawArc(50,50,200,200, -90*16, 90*16);…

ubuntu18安装opensips3.4,开启ws/wss/http接口模块

、如果是centos 7安装则使用yum 命令。 添加库地址注意系统类型,选择对应的系统类型和版本 curl https://apt.opensips.org/opensips-org.gpg -o /usr/share/keyrings/opensips-org.gpg echo "deb [signed-by/usr/share/keyrings/opensips-org.gpg] https:/…

neo4j所有关系只显示RELATION,而不显示具体的关系

当看r时,真正的关系在properties中的type里,而type为“RELATION” 造成这个的原因是: 在创建关系时,需要指定关系的类型,这是固定的,不能像属性那样从CSV文件的一个字段动态赋值。标准的Cypher查询语言不支…

人工智能之Tensorflow变量作用域

在TensoFlow中有两个作用域(Scope),一个时name_scope ,另一个是variable_scope。variable_scope主要给variable_name加前缀,也可以给op_name加前缀;name_scope给op_name加前缀。 variable_scope 通过所给的名字创建或…

Stable diffusion(四)

训练自己的Lora 【DataSet】【Lora trainer】【SD Lora trainer】 前置的知识 batch size:模型一次性处理几张图片。一次性多处理图片,模型能够综合捕捉多张图片的特征,最终的成品效果可能会好。但是处理多个batch size也意味着更大的显存…

nvm更换node.js的版本

自行下载nvm 打开cmd 1. nvm ls 列出目前已经下载的node版本,和正在使用的node版本 2. nvm install v版本号 下载某个版本 3. nvm uninstall v版本号 卸载某个版本 4. nvm use 版本号 切换到某个版本

深入理解栈和队列(二):队列

个人主页:17_Kevin-CSDN博客 专栏:《数据结构》 一、队列的概念和结构 队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操作的…

吴恩达2022机器学习专项课程(一) 3.5 可视化成本函数

问题预览 为什么要可视化成本函数?可视化之后的成本函数是什么样子?如何在三维空间里通过w和b找到一个成本函数的值?如何在三维空间里找到成本函数的最小值? 解读 可视化成本函数:为了更加方便的看到不同的w和b&…

AI:152- 利用深度学习进行手势识别与控制

本文收录于专栏:精通AI实战千例专栏合集 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 每一个案例都附带关键代码,详细讲解供大家学习,希望可以帮到大家。正在不断更新中~ 一. 利用深度学习进行手势识别与控制 …

Acrobat Pro DC ----专业PDF编辑与管理

Acrobat Pro DC 2023是一款功能强大的PDF处理软件,它提供了丰富的编辑工具,支持创建、编辑、合并、分割PDF文件,以及高质量的PDF到其他格式的转换功能。同时,该软件集成了最新的OCR技术,可将扫描文档或图片转换成可编辑…

转座子插入位点分析4------PS转座子测序数据分析

观察数据 这是经公司使用fastp质控后的数据,我们先挑选部分数据进行比对,观察序列结构 为了准确性,我们再次挑选另一批数据进行比对 可以看到,所有序列都存在一个“GTGTCAAATACTTATTTTCCCCGCTGTA”的前导序列,这可能…

uniapp页面嵌套其他页面的实现

功能: 类似于一个drawer&#xff0c;当主页面加载的时候会一并加载url对应的组件&#xff0c;当点击后以drawer形式显示组件里面的内容&#xff0c;可动画。 <navigator url"/pages/my/components/personalMessage" slot"right"><view><di…

Java螺旋折线

题目描述 如图所示的螺旋折线经过平面上所有整点恰好一次。 对于整点 (X,Y)&#xff0c;我们定义它到原点的距离dis(X,Y) 是从原点到 (X,Y) 的螺旋折线段的长度。 例如 dis(0,1)3&#xff0c;dis(−2,−1)9。 给出整点坐标 (X,Y)&#xff0c;你能计算出 dis(X,Y) 吗&#xf…

GO-初识包管理

初识包管理&#xff0c;知道项目中文件和文件夹之间的关系 输出&#xff0c;代码&#xff0c;在go编译器运行时会显示在屏幕中 初识数据类型 整型&#xff0c;数字。例如&#xff1a;1、2、3、4 字符串类型&#xff0c;表示文本信息的。例如:“张三”“李四” 布尔类型&#x…

图解Kafka架构学习笔记(三)

准备Kafka环境 这里推荐使用Docker Compose快速搭建一套本地开发环境。 以下docker-compose.yml文件用来搭建一套单节点zookeeper和单节点kafka环境&#xff0c;并且在8080端口提供kafka-ui管理界面。 version: 2.1services:zoo1:image: confluentinc/cp-zookeeper:7.3.2hos…

FPGA 以太网传输ov5640视频

1 实验任务 使用 DFZU4EV MPSoC 开发板及双目 OV5640 摄像头其中一个摄像头实现图像采集&#xff0c;并通过开发板上的以太网接口发送给上位机实时显示。 2 系统框架 时钟模块用于为 I2C 驱动模块、以太网顶层模块和开始传输控制模块提供驱动时钟&#xff1b;I2C 驱动模块…

Python Flask 自定义错误页面

新建templates/404.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <img src"../static/a123.png" alt"" width"…

基于spring boot的个人博客系统的设计与实现(带源码)

随着国内市场经济这几十年来的蓬勃发展&#xff0c;突然遇到了从国外传入国内的互联网技术&#xff0c;互联网产业从开始的群众不信任&#xff0c;到现在的离不开&#xff0c;中间经历了很多挫折。本次开发的个人博客系统&#xff0c;有管理员&#xff0c;用户&#xff0c;博主…

使能 Linux 内核自带的 FlexCAN 驱动

一. 简介 前面一篇文章学习了 ALPHA开发板修改CAN的设备树节点信息&#xff0c;并加载测试过设备树文件&#xff0c;文件如下&#xff1a; ALPHA开发板修改CAN的设备树节点信息-CSDN博客 本文是学习使能 IMX6ULL的 CAN驱动&#xff0c;也就是通过内核配置来实现。 二. 使能…