在Java中为什么HashMap线程不安全_Java并发风险解析
发布时间 - 2026-01-02 00:00:00 点击率:次HashMap线程不安全,因put非原子、扩容死循环(JDK1.7)、迭代时修改异常及脏读漏读;应选用ConcurrentHashMap,但需注意其弱一致性与size估算特性。
put操作非原子性导致数据覆盖
多个线程同时对同一个 key 调用 put,极大概率丢失数据——这不是偶发bug,而是设计使然。因为 putVal 方法中“检查 key 是否存在”和“插入新节点”是两个独立步骤,中间没有任何同步机制。
- 线程A读取桶位置为空,准备插入;此时CPU切换到线程B,B完成插入并更新
size - 线程A恢复后,仍按“空桶”逻辑插入,直接覆盖B写入的值
- 即使key不同,若哈希冲突落在同一桶,链表头插(JDK 1.7)或尾插(JDK 1.8)过程中的指针重赋值也可能被并发打断
扩容(resize)引发死循环(JDK 1.7特有)
JDK 1.7 的 resize 使用头插法迁移链表,多线程并发执行时,两个线程反复反转同一链表,极易形成环形链表。一旦形成,后续任意线程调用 get 遍历该桶,就会陷入无限循环,CPU飙升到100%。
- 该问题在 JDK 1.8 中已通过改用尾插法规避,但不等于线程安全了——只是把最危险的死循环换成了更隐蔽的数据不一致
- 即便JDK 1.8,多线程同时触发扩容仍会导致部分线程的扩容结果被丢弃,
table数组更新丢失,新增元素“消失”
迭代时修改触发ConcurrentModificationException
这是最容易被观察到的线程不安全表现:一个线程正在用 entrySet().iterator() 遍历,另一个线程执行 put 或 remove,几乎必然抛出 ConcurrentModificationException。
- 根本原因是
modCount变量未被 volatile 修饰,且迭代器只做简单计数校验,不提供同步保障 - 这个异常不是“保护机制”,而是 fail-fast 的事后报错——它不阻止并发修改发生,只在检测到不一致时中断
- 注意:即使没抛异常,
也可能返回脏读、漏读或重复数据(尤其在扩容中途被读)
正确替代方案怎么选?ConcurrentHashMap不是万能解药
别再用 synchronized(new HashMap()) 或 Hashtable——前者锁粒度太粗,后者已被官方标记为遗留类,性能差且不支持 null 键值。
-
ConcurrentHashMap是首选:JDK 1.8 后取消分段锁(Segment),改用synchronized+ CAS 控制桶级锁,读操作完全无锁,写操作仅锁单个桶 - 若需强一致性(如遍历时要求看到全部已提交修改),
ConcurrentHashMap的弱一致性语义可能不够——此时应考虑加业务层锁,或改用CopyOnWriteMap(仅适用于读远多于写的极低频写场景) - 切记:
ConcurrentHashMap的size()方法返回的是估算值,高并发下可能不准;如需精确计数,得配合LongAdder等原子计数器
真正容易被忽略的点是:哪怕你只用 get,只要其他线程在并发 put 或扩容,就可能读到过期值或 null(尤其在 JDK 1.7/1.8 初期版本)。线程安全从来不是“某个方法安全”,而是整个操作序列的可见性与原子性保障。
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何用美橙互联一键搭建多站合一网站?
如何用AI帮你把自己的生活经历写成一个有趣的故事?
Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
青岛网站建设如何选择本地服务器?
简历没回改:利用AI润色让你的文字更专业
简单实现Android文件上传
Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
如何在阿里云高效完成企业建站全流程?
如何快速打造个性化非模板自助建站?
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制
制作电商网页,电商供应链怎么做?
原生JS获取元素集合的子元素宽度实例
魔方云NAT建站如何实现端口转发?
JavaScript Ajax实现异步通信
如何用好域名打造高点击率的自主建站?
Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
Laravel如何构建RESTful API_Laravel标准化API接口开发指南
jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】
Win11关机界面怎么改_Win11自定义关机画面设置【工具】
Laravel如何使用.env文件管理环境变量?(最佳实践)
Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程
如何快速生成ASP一键建站模板并优化安全性?
西安专业网站制作公司有哪些,陕西省建行官方网站?
Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)
韩国服务器如何优化跨境访问实现高效连接?
Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧
,在苏州找工作,上哪个网站比较好?
JavaScript如何实现音频处理_Web Audio API如何工作?
网站制作壁纸教程视频,电脑壁纸网站?
长沙做网站要多少钱,长沙国安网络怎么样?
简单实现Android验证码
java ZXing生成二维码及条码实例分享
html5audio标签播放结束怎么触发事件_onended回调方法【教程】
奇安信“盘古石”团队突破 iOS 26.1 提权
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
Laravel如何生成API文档?(Swagger/OpenAPI教程)
悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音
浅谈javascript alert和confirm的美化
Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区
如何快速搭建高效可靠的建站解决方案?
如何快速生成可下载的建站源码工具?
HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】
大型企业网站制作流程,做网站需要注册公司吗?
手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?
如何登录建站主机?访问步骤全解析


也可能返回脏读、漏读或重复数据(尤其在扩容中途被读)