深入剖析 ConcurrentHashMap:Java 并发编程的基石

目录

【1】Java 7 中 ConcurrentHashMap 的实现原理

1.分段锁(Segment)

2. 数据结构

3. 操作流程

【2】Java 8 中 ConcurrentHashMap 的改进

1.红黑树的引入

2.CAS 操作

3.数据结构的变化

【3】ConcurrentHashMap 的常用方法及使用示例

1.put(K key, V value)

2.get(Object key)

3.computeIfAbsent(K key, FunctionmappingFunction)

4.forEach(BiConsumeraction)

【4】使用场景

【5】总结


        ConcurrentHashMap是一个支持高并发的哈希表(类似HashMap)。与Hashtable不同,该类不依赖于synchronization去保证线程操作的安全。


【1】Java 7 中 ConcurrentHashMap 的实现原理

1.分段锁(Segment)

        ConcurrentHashMap内部维护了一个Segment数组,每个Segment都是一个独立的锁,类似于一个小的HashTable。默认情况下,ConcurrentHashMap被分为 16 个Segment,这意味着理论上可以支持 16 个线程同时进行写入操作(前提是操作的是不同的Segment)。

2. 数据结构

        每个Segment内部又维护了一个HashEntry数组,用于存储实际的键值对。HashEntry是一个链表结构,当发生哈希冲突时,新的元素会被添加到链表的头部。

3. 操作流程

  • get 操作:通过哈希算法计算出键对应的Segment索引,然后在对应的Segment中查找链表,找到对应的键值对。由于get操作并不需要对整个ConcurrentHashMap加锁,所以性能较高。

  • put 操作:同样先确定Segment索引,对对应的Segment加锁,然后在链表中查找或插入键值对。如果链表长度超过一定阈值,会进行扩容操作。


【2】Java 8 中 ConcurrentHashMap 的改进

1.红黑树的引入

        在 Java 8 中,当链表长度超过 8 时,会将链表转换为红黑树。这是因为在哈希冲突较多的情况下,链表的查询时间复杂度为 O (n),而红黑树的查询时间复杂度为 O (log n),大大提高了查询效率。

2.CAS 操作

        ConcurrentHashMap在一些操作中使用了 CAS 操作来避免锁竞争。例如在插入元素时,首先尝试使用 CAS 操作直接插入,如果失败再进行加锁操作。这样可以减少锁的使用,提高并发性能。

3.数据结构的变化

        Java 8 中的ConcurrentHashMap不再使用Segment数组,而是直接使用一个Node数组来存储数据。Node节点有三种形态:普通节点(链表节点)、红黑树节点和 ForwardingNode(用于扩容时的标识节点)。


【3】ConcurrentHashMap 的常用方法及使用示例

1.put(K key, V value)

将指定的键值对插入到ConcurrentHashMap中。

ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("apple", 10);

2.get(Object key)

根据指定的键获取对应的值。

Integer value = map.get("apple");
System.out.println(value); // 输出10

3.computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)

如果指定的键不存在,则根据提供的映射函数计算出值并插入到ConcurrentHashMap中。

map.computeIfAbsent("banana", k -> 5);

4.forEach(BiConsumer<? super K,? super V> action)

遍历ConcurrentHashMap中的每一个键值对,并对其执行指定的操作。

map.forEach((k, v) -> System.out.println(k + ": " + v));


【4】使用场景

  • 缓存系统:在缓存系统中,ConcurrentHashMap可以用来存储缓存数据,多线程可以同时读取和更新缓存,保证缓存的高效性和一致性。

  • 计数器:用于统计一些并发的计数场景,如网站的访问量统计、任务的执行次数统计等,多个线程可以同时对计数器进行递增操作。

  • 多线程任务的结果存储:在多线程计算任务中,每个线程计算的结果可以存储到ConcurrentHashMap中,最后汇总所有结果。


【5】总结

        ConcurrentHashMap作为 Java 并发编程中的重要组件,不断演进和优化,为我们在多线程环境下提供了高效、安全的数据存储解决方案。通过深入理解它的实现原理、特性和使用方法,开发者可以更好地在实际项目中运用它,提升系统的并发性能和稳定性。随着 Java 技术的不断发展,相信ConcurrentHashMap还会带来更多的惊喜和优化。


        感谢你花时间读到这里~ 如果你觉得这篇内容对你有帮助,不妨点个赞让更多人看到;如果有任何想法、疑问,或者想分享你的相关经历,欢迎在评论区留言交流,你的每一条互动对我来说都很珍贵~ 我们下次再见啦!😊😊

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

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

相关文章

【会员专享数据】2020-2022年我国乡镇的逐日地表气压数据(Shp/Excel格式)

之前我们分享过2020—2022年中国0.01分辨率逐日地表气压栅格数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff01;该数据是研究者张凌, 胡英屹等发布在国家冰川冻土沙漠科学数据中心平台上的高分辨地表气压数据。很多小伙伴拿到数据后反馈栅格数据不太方便使用&a…

第二阶段WinForm-12:UI控件库

1_验证码与条形码 1.1_条码基础知识 条码&#xff1a;条码是由一组按一定编码规则排列的条、空符号组成&#xff0c;用以表示一定的字符、数字及符号组成的信息 1.2_一维码 &#xff08;1&#xff09;Code 128 Code 128 是一种密度很高的字母数字代码系统&#xff0c;可对其…

别再误会了!Redis 6.0 的多线程,和你想象的完全不一样

技术解析核心误区&#xff1a;Redis 6.0是完全多线程的吗&#xff1f;No. Redis 6.0引入的多线程&#xff0c;只用于网络I/O的读写和数据的解析。而核心的命令执行&#xff08;比如 GET, SET, HGETALL 等&#xff09;依然是单线程的。Redis的架构演进&#xff0c;就像是把一个复…

23种设计模式——抽象工厂模式(Abstract Factory Pattern)详解

✅作者简介&#xff1a;大家好&#xff0c;我是 Meteors., 向往着更加简洁高效的代码写法与编程方式&#xff0c;持续分享Java技术内容。 &#x1f34e;个人主页&#xff1a;Meteors.的博客 &#x1f49e;当前专栏&#xff1a;设计模式 ✨特色专栏&#xff1a;知识分享 &#x…

本地部署开源数据生成器项目实战指南

本地部署开源数据生成器项目实战指南 前言 在当今大数据和人工智能时代&#xff0c;高质量数据集对于模型训练和算法开发至关重要。然而&#xff0c;获取真实且合规的数据集往往面临隐私、成本和法律等多重挑战。合成数据生成技术为此提供了优雅的解决方案&#xff0c;它能够…

2025React面试题集锦

1. React 是什么?它有哪些主要特点? React 是由Facebook开发的开源JavaScript库,用于构建用户界面(UI),尤其适合开发复杂的单页应用(SPA)。 主要特点: 声明式编程:只需描述UI应该是什么样子(如return <div>Hello</div>),React会自动处理DOM更新,无需…

设计模式:迭代器模式(Iterator Pattern)

文章目录一、概念二、实例分析三、示例代码一、概念 迭代器模式 是一种 行为型设计模式&#xff0c;用于在不暴露集合对象内部结构的前提下&#xff0c;顺序访问集合中的元素。 换句话说&#xff1a; 集合类只负责数据存储&#xff1b;迭代器类负责遍历集合&#xff1b;使用者…

Vue 3 学习路线指南

阶段一:基础入门 (1-2周) 1.1 环境准备 # 安装 Node.js (推荐 18+ 版本) # 安装 Vue CLI 或使用 Vite npm create vue@latest my-vue-app cd my-vue-app npm install npm run dev1.2 Vue 3 核心概念 响应式系统:ref(), reactive(), computed() 组合式 API:setup() 函数 模…

使用 `hover:not-[:has(:hover)]` 避免「父元素和子元素同时 hover」时的样式冲突

:hover:not-(:has(:hover)) has() CSS 4 引入的“父选择器”&#xff0c;意思是&#xff1a;匹配那些里面包含某个子元素/状态的元素。 例如&#xff1a;:has(:hover) 表示「自身包含正在被 hover 的子元素」。 :not() 取反伪类&#xff0c;表示不匹配里面的条件。 比如我…

第三十天-DMA串口实验

一、DMA概述二、DMA通道注意&#xff0c;想要往串口中写数据&#xff0c;外部请求信号应该是USARTx_TX&#xff0c;当DR寄存器为空时&#xff0c;产生TX信号&#xff0c;请求DMA。反之&#xff0c;从串口中读数据&#xff0c;外部请求信号应该是USARTx_RX&#xff0c;当DR寄存器…

C/C++ 中的inline(内联函数关键字)详解

在 C/C 编程中&#xff0c;函数调用虽然带来了代码复用和可读性提升&#xff0c;但频繁调用小型函数可能会产生额外的调用开销&#xff08;call overhead&#xff09;&#xff0c;比如栈帧的建立与销毁、参数传递等。 为了减少这种开销&#xff0c;C 引入了 inline&#xff08;…

2025 年高教社杯全国大学生数学建模竞赛A 题 烟幕干扰弹的投放策略完整成品 思路 模型 代码 结果 全网首发高质量!!!

烟幕干扰弹主要通过化学燃烧或爆炸分散形成烟幕或气溶胶云团,在目标前方特定空域形成遮蔽&#xff0c;干扰敌方导弹&#xff0c;具有成本低、效费比高等优点。随着烟幕干扰技术的不断发展&#xff0c;现已有多种投放方式完成烟幕干扰弹的定点精确抛撒,即在抛撒前能精确控制烟幕…

嵌入式第四十五天(51单片机相关)

一.1.CPU、MPU、MCU、GPU&#xff1a; CPU&#xff08;中央处理器&#xff09;&#xff1a;计算机的核心部件&#xff0c;负责执行指令和处理数据。 MPU&#xff08;微处理器&#xff09;&#xff1a;通常指更通用的处理器&#xff0c;强调计算能力。 MCU&#xff08;微控制器&…

今天面了一个Java后端工程师,真的让我猛抬头

今天面了一个Java后端工程师,真的让我猛抬头啊. 现在面试不像传统的八股文面试,我更多问的都是项目场景相关的问题,但是都能回答的不错.这一点我还是很惊讶的。 不仅如此,她的技术也很扎实,对Java核心机制&#xff08;JVM、并发、集合等&#xff09;理解深入&#xff0c;回答…

拦截器和过滤器(理论+实操)

拦截器和过滤器 本文旨在夯实基础以及实战加深理解,目的是更深的理解以便掌握,希望能跟着动手敲一遍,绝对受益匪浅 在本文,我会先给出两者的区别(理论知识),随后是两者各自的实操实现 文章目录拦截器和过滤器什么是过滤器和拦截器?1.过滤器2.拦截器执行整体流程拦截器和过滤器…

HTB 赛季8靶场 - Guardian

各位好&#xff0c;最近我的kali崩掉了&#xff0c;崩掉了&#xff0c;建议大家避K 番茄C盘瘦身&#xff0c;这家伙修改了我的avrt.dll文件&#xff0c;导致virtualbox不接受我的avrt.dll文件的签名了&#xff0c;从而导致virtualbox的虚拟机环境全崩无法开机。弄了几天&#x…

Rust+slint实现一个登录demo

系列文章目录 文章目录系列文章目录前言一、为什么前端选择slint而不是Tauri或者其他GUI框架二、开发工具三、代码编写项目结构前端代码编写后端开发编写运行效果总结前言 本文章就是一个简单rust全栈编程的一个小小的示例供rust新手阅读学习。 一、为什么前端选择slint而不是…

2025前端面试题及答案(详细)

HTML5 的新特性有哪些&#xff1f;简约版本&#xff1a;“HTML5 新特性主要体现在六个方面&#xff1a; 第一&#xff0c;语义化标签&#xff0c;比如 header、footer、nav 等&#xff0c;让页面结构更清晰&#xff1b; 第二&#xff0c;表单增强&#xff0c;新增了 date、emai…

分词器详解(二)

&#x1f50d; 第2层&#xff1a;中等深度&#xff08;15分钟理解&#xff09; 1. 理论基础 1.1 BPE的数学原理 核心思想&#xff1a;通过迭代合并高频字符对构建词汇表 算法形式化&#xff1a; 初始化词汇表 V0{c1,c2,...,cn}V_0 \{c_1, c_2, ..., c_n\}V0​{c1​,c2​,...,c…

嵌入式学习 51单片机(3)

UART 概述通用异步收发器&#xff08;UART&#xff09;是一种全双工、串行、异步通信协议&#xff0c;常用于设备间数据传输。包含两根信号线&#xff1a;RXD&#xff08;接收信号线&#xff09;TXD&#xff08;发送信号线&#xff09;通信方式单工通信方向固定&#xff0c;仅支…