Java ConcurrentHashMap 详解 📅 发布时间:2026/7/13 4:40:07 👁️ 浏览次数: 1. ConcurrentHashMap 是什么ConcurrentHashMap是 Java 并发包 (java.util.concurrent) 中提供的一个线程安全的哈希表实现。它的主要设计目标是在保证线程安全的前提下提供比Hashtable更高的并发性能同时尽量保持与HashMap相当的空间和时间效率。简单来说它就是专门为高并发环境设计的HashMap。2. 核心理解从大锁到精细化管理的演进理解ConcurrentHashMap的关键在于看懂它为了高性能并发在锁的粒度上做的两次重要演进。特性JDK 1.7 及之前JDK 1.8 及之后数据结构Segment数组 HashEntry数组 链表Node数组 链表 / 红黑树并发机制分段锁(ReentrantLock)CAS synchronized(锁桶的头节点)锁粒度每个Segment一段数据默认16个每个数组桶Bucket的头节点扩容每个Segment内部独立扩容多线程协同扩容优点实现相对简单并发度有上限并发度极高结构简单适应多核CPU从上表可以清晰地看到JDK 1.8 版本的ConcurrentHashMap完成了一次质的飞跃JDK 1.7的思路是分而治之。它将数据分成多个段Segment每个段独立加锁。这就像把一个大仓库分成多个独立的小隔间每个隔间都有自己的门锁不同的人可以同时进入不同的隔间从而提升了并发度。JDK 1.8的思路是精益求精。它放弃了Segment的概念直接将锁的粒度细化到每个数组桶Bucket的头节点。这相当于把仓库的管理粒度精细到了每个货架。同时它还引入了CASCompare And Swap无锁算法在很多场景下避免了使用锁性能得到了极大的提升。3. 源码原理深度解析 (以JDK 1.8为准)接下来我们从源码层面来看看 JDK 1.8 的ConcurrentHashMap是如何实现高性能并发的。3.1 核心机制CAS synchronized volatile这是 JDK 1.8 并发控制的三驾马车。volatile关键变量如table数组、sizeCtl都被volatile修饰保证了多线程之间的内存可见性。一个线程修改了值其他线程能立即看到。CAS (Compare And Swap)一种乐观锁技术用于无锁状态下的值更新。常用于初始化、空桶插入、更新计数等场景避免了线程阻塞效率极高。synchronized在需要真正锁住资源时如向非空桶中插入节点只对桶的头节点加锁。得益于JDK 1.6后对synchronized的性能优化它的开销已经很小。3.2 构造方法与懒加载ConcurrentHashMap的构造方法非常轻量它并不会立即初始化内部数组只是设置了一些关键参数。真正的数组初始化是在第一次插入数据时putVal方法才触发的这种机制被称为懒加载。// 构造时只计算了table的初始容量并赋值给sizeCtl并未创建table数组publicConcurrentHashMap(intinitialCapacity){// ... 参数校验intcap((initialCapacity(MAXIMUM_CAPACITY1))?MAXIMUM_CAPACITY:tableSizeFor(initialCapacity(initialCapacity1)1));this.sizeCtlcap;// sizeCtl 在这里是一个扩容阈值}3.3 put 方法的执行流程put方法是理解其并发设计的核心入口。计算哈希通过spread()方法对key的hashCode进行二次扰动让分布更均匀。进入死循环使用for (;;)自旋确保操作最终成功。检查并初始化数组如果table为空则调用initTable()进行懒加载。此方法内部会通过CAS竞争sizeCtl变量只有一个线程能成功执行初始化。定位空桶并CAS插入根据哈希找到对应的数组桶i。如果该桶为null则尝试通过CAS将新节点放入。如果CAS成功则直接结束否则说明有其他线程竞争进入下一轮自旋。检测到正在扩容并协助如果发现桶的头节点hash值为MOVED-1说明当前table正在扩容。此时当前线程不会傻等而是调用helpTransfer()方法加入扩容大军一起帮忙体现了我为人人人人为我的协作精神。锁定桶并进行插入如果以上情况都不满足说明该桶已经存在数据链表或红黑树。此时会对桶的头节点f加synchronized锁。拿到锁后再次确认头节点未被修改然后遍历链表或红黑树进行插入或更新操作。检查并树化插入完成后检查当前桶的链表长度是否超过阈值TREEIFY_THRESHOLD8如果超过则调用treeifyBin()尝试将链表转为红黑树前提是数组长度 64。增加元素计数最后调用addCount(1L, binCount)原子性地增加Map的元素个数。3.4 扩容原理多线程协同JDK 1.8 的扩容是其最精妙的设计之一。触发条件当put操作后元素总数超过sizeCtl阈值时触发扩容。协同机制第一个发现需要扩容的线程会创建一个大一倍的nextTable。它会将任务进行分片通过transferIndex变量指示下一个要迁移的桶区间。其他线程在put或get时如果发现ForwardingNode标志节点表示该桶已迁移就会调用helpTransfer方法参与进来领取一部分桶的迁移任务。ForwardingNode这是一个占位节点。在扩容过程中当一个桶迁移完成后就会在旧数组的对应位置放一个ForwardingNode。任何后续线程访问到这个节点就知道要去新的nextTable中查找数据或参与迁移。4. ConcurrentHashMap 用来做什么它是高并发场景下的万能钥匙主要用途包括作为线程安全的共享缓存在Web服务器、微服务应用中作为全局缓存供大量请求线程并发读写而无需额外加锁。实现计数器或多重映射结合LongAdder和computeIfAbsent等原子方法可以轻松实现一个高性能的并发计数器或频率统计器。存储配置信息或上下文在复杂的多线程应用中作为共享的配置中心或上下文容器。避免显式同步当需要一个Map在多线程间共享时首选ConcurrentHashMap它内部已经实现了所有必要的同步控制。5. 重要特性与注意事项不允许null键和值ConcurrentHashMap的key和value都不能为null。这是为了避免在并发环境下的二义性——当get(key)返回null时你无法判断是键不存在还是值本身就为null。弱一致性迭代器、get方法、size方法等都具有弱一致性。例如当你用迭代器遍历时如果在遍历过程中有其他线程修改了Map迭代器不会抛出ConcurrentModificationException但它不一定能反映最新的修改。这种设计牺牲了强一致性换取了极致的并发性能。批量操作提供了forEach、search、reduce等批量操作并支持并行执行可以充分利用多核CPU的计算能力。总结ConcurrentHashMap是Java并发编程智慧的结晶。从 JDK 1.7 的分段锁到 JDK 1.8 的CAS synchronized 桶锁 多线程协同扩容它的演进过程清晰地展示了通过不断细化锁粒度、利用无锁技术来最大化并发性能的设计思想。在实际开发中只要涉及到多线程共享的Map它都应该是你的首选。
大数据基于Python的大模型岗位人才需求可视化分析 目录大数据与大模型岗位人才需求可视化分析实现计划数据采集与清洗数据存储与管理特征分析与建模可视化实现技术栈选型交付物时间规划开发技术路线源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!大数据与大模型岗位人才需求可视化分析实现… 2026/7/11 21:19:56
中间件实用笔记 Redis Redis集群部署 部署架构 服务器节点:192.168.198.132, 192.168.198.133, 192.168.198.134集群架构:三主(Master)三从(Slave)端口规划: 每台服务器部署两个 Redis 实… 2026/7/10 10:39:52
从零开始学 Python 后端开发,到能入职需要多久?一份真实学习路线参考 很多刚接触编程的同学都会问一个非常现实的问题:从零开始学习 Python 后端开发,到可以找到一份工作,大概需要多久?其实答案并不是一个固定的时间,因为每个人的学习时间、学习方式、基础水平都不同。但根据大量开发者的… 2026/7/6 21:20:57
基于ADS127L11和PIC18F26K22的高精度数据采集系统设计 1. 项目概述:高精度模拟信号数字化方案在工业测量、医疗设备和科学仪器等领域,我们经常需要将微弱的模拟信号转换为高精度的数字信号。这次要分享的是基于TI的ADS127L11 Δ-Σ ADC和Microchip的PIC18F26K22 MCU搭建的高精度数据采集系统。这个组合特别适… 2026/7/13 4:37:21
零基础实战!Prompt工程→Context上下文工程→Harness驾驭工程→Loop循环工程:从普通提问→精准输出→可控合规→自动纠错(小白直接套用) 零基础实战!Prompt工程→Context上下文工程→Harness驾驭工程→Loop循环工程:从普通提问→精准输出→可控合规→自动纠错(小白直接套用) 前言 上一篇文章我完整讲清了提示词四代演化逻辑:Prompt工程→Context上下文工程… 2026/7/13 4:35:20
STM32与蓝牙音频模块开发实战:低延迟与高音质方案 1. 项目背景与硬件选型解析在嵌入式音频开发领域,蓝牙无线传输一直面临着延迟、音质损耗和功耗三大挑战。IDC777-1蓝牙音频模块与STM32L496AG微控制器的组合,恰好针对这些痛点提供了完整的解决方案。这套方案最吸引我的地方在于它同时支持传统蓝牙音频&a… 2026/7/13 4:35:20
从0入门!提示词技术完整演化路线:提示词→上下文→驾驭→循环工程,纯概念小白教程 从0入门!提示词技术完整演化路线:提示词→上下文→驾驭→循环工程,纯概念小白教程 前言 很多新手只会随便丢一句话提问AI,输出效果时好时坏,不知道提示词早已迭代四代,单纯修改文字早已不够用。今天从零拆… 2026/7/13 4:35:20
MCP3428与PIC18F86K22高精度数据采集系统设计 1. 为什么选择MCP3428与PIC18F86K22组合在工业现场和实验室环境中,数据采集系统的精度和稳定性往往直接决定最终数据的可靠性。MCP3428作为一款18位Δ-Σ ADC(模数转换器),其核心优势在于集成了可编程增益放大器(PGA)和内部基准电… 2026/7/13 4:33:19
AI音乐生成提示词设计指南:从零创作专业级歌曲 你是否曾经听过一首爆款歌曲,心里想着"这旋律真不错,我也能写出来",但一想到需要学习乐理、编曲软件、乐器演奏,就望而却步?现在,AI音乐生成工具Suno正在彻底改变这一局面。Suno不是简单的音乐拼… 2026/7/13 4:33:19
HS2-HF Patch终极指南:如何用3步解决Honey Select 2的70+个痛点 HS2-HF Patch终极指南:如何用3步解决Honey Select 2的70个痛点 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 你是否曾经在Honey Select 2中遇到过… 2026/7/13 0:01:19
语音转文字工具AsrTools:让音频整理变得简单高效 语音转文字工具AsrTools:让音频整理变得简单高效 【免费下载链接】AsrTools ✨ AsrTools: Smart Voice-to-Text Tool | Efficient Batch Processing | User-Friendly Interface | No GPU Required | Supports SRT/TXT Output | Turn your audio into accurate text … 2026/7/13 0:03:19
基于深度学习的蘑菇或花卉或动漫人物或中草药货水果蔬菜等识别系统31(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_ 基于深度学习的蘑菇或花卉或动漫人物或中草药货水果蔬菜等识别系统31(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_ 独家界面!不会重复,此项目属于本人原创,若有雷同,均是盗卖,各位买… 2026/7/13 0:05:20
Git reset 与 revert 深度对比:5个关键差异与 3 种典型应用场景 Git Reset 与 Revert 深度对比:5个关键差异与3种典型应用场景在团队协作开发中,代码版本管理如同行走钢丝——一步失误可能导致整个项目陷入混乱。作为Git进阶用户,你是否曾在深夜面对错误的提交束手无策?是否在强制推送后收到同事… 2026/7/12 0:01:13
GitHub 学生包申请避坑:5个常见失败原因与开发者工具调试方案 GitHub 学生包申请技术排障指南:5个高频失败场景与开发者工具实战方案第一次尝试申请GitHub学生包时,我盯着屏幕上那个不断转圈的加载动画整整15分钟,最终只等来了一行冰冷的错误提示。这可能是许多开发者共同的经历——明明按照教程操作&… 2026/7/12 0:01:13
冒烟测试用例设计规范:5%-10%覆盖率下的3类核心场景与执行标准 冒烟测试用例设计的黄金法则:5%-10%覆盖率下的精准筛选策略在快节奏的敏捷开发环境中,冒烟测试作为质量保障的第一道防线,其重要性不言而喻。当测试资源有限而时间紧迫时,如何从海量测试用例中精准筛选出那关键的5%-10%࿰… 2026/7/13 2:34:55