讲师中心 微信公众号
AI工具推荐 视频效率加速

Java中ConcurrentModificationException异常处理

千辰姑娘_9927

千辰姑娘_9927

发布时间:2026-01-09 04:27:25

|

914人浏览过

|

来源于php中文网

原创

ConcurrentModificationException是单线程下“边迭代边修改”触发的fail-fast机制,非多线程并发导致;底层通过modCount与expectedModCount比对检测结构变更,不一致则抛异常。

java中concurrentmodificationexception异常处理

为什么遍历集合时修改会抛出ConcurrentModificationException

这个异常不是因为多线程并发导致的(虽然名字容易误导),而是ArrayList、HashMap等非线程安全集合在单线程中「边迭代边修改」触发了快速失败(fail-fast)机制。底层靠modCount计数器检测结构变更:每次调用add()、remove()等方法都会递增它,而迭代器在next()或hasNext()时会校验当前modCount是否与初始化时一致,不一致就直接抛异常。

常见错误现象:

  • 用for-each循环遍历ArrayList,内部调用iterator(),然后在循环体里调用list.remove(obj)
  • 用Iterator遍历,但调用的是集合自身的remove()而非iterator.remove()
  • 多个线程共用同一个ArrayList,一个在读(遍历),一个在写(增删)

单线程下安全删除元素的正确方式

核心原则:必须通过迭代器自身提供的remove()方法来删除当前元素,它会同步更新expectedModCount,避免校验失败。

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if ("b".equals(s)) {
        it.remove(); // ✅ 正确:调用迭代器的 remove()
    }
}

其他可行方案:

立即学习“Java免费学习笔记(深入)”;

Java注释规范Skills
Java注释规范Skills

当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。

下载
  • 收集待删元素,遍历结束后统一调用list.removeAll(toRemove)
  • 使用removeIf()(Java 8+):list.removeIf(s -> "b".equals(s))
  • 倒序索引遍历(仅适用于ArrayList等支持随机访问的集合):for (int i = list.size() - 1; i >= 0; i--) { if (needRemove(list.get(i))) list.remove(i); }

多线程环境下的替代集合选择

如果确实需要多线程并发读写且遍历时不报错,不能靠加锁硬扛(锁住整个遍历过程性能差、易死锁),应换用线程安全的集合实现:

  • CopyOnWriteArrayList:适合读多写少场景;遍历时操作的是快照,写操作会复制整个数组,Iterator不支持remove()
  • ConcurrentHashMap:迭代其keySet()、values()或entrySet()不会抛ConcurrentModificationException,但结果可能不反映实时状态(弱一致性)
  • BlockingQueue子类(如LinkedBlockingQueue):适用于生产者-消费者模型,提供线程安全的增删操作

注意:Vector和Hashtable虽是线程安全的,但它们的迭代器仍是fail-fast的,同样会抛该异常。

调试时如何快速定位问题源头

异常堆栈通常只显示在next()或hasNext()处抛出,但真正引发modCount变化的位置往往在别处。关键看异常信息中的「at」行和上层调用链:

  • 检查堆栈中是否有remove()、add()、clear()等结构修改方法出现在迭代逻辑附近
  • 确认是否在Lambda表达式、Stream操作(如forEach)中隐式调用了集合修改方法
  • 留意匿名内部类或监听器回调里是否意外修改了外部集合

最容易被忽略的一点:即使你没显式写remove(),某些工具方法(比如Collections.synchronizedList()包装后返回的代理对象,其iterator()仍不支持并发修改)也会导致相同行为——它只是同步了单个方法,没解决迭代器一致性问题。

热门AI工具

更多
Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

相关专题

更多
php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

798

2025.12.04

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

798

2025.12.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6679

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3225

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4168

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2865

2025.08.29

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

1051

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

345

2025.11.08

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

60

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn