ConcurrentModificationException并发修改异常

本文介绍了并发修改异常的概念,即在使用迭代器遍历集合时若集合被修改则会抛出此异常。文章提供了两种解决方案:一是使用ListIterator进行迭代;二是采用get方法遍历。

并发修改异常是指当方法检测到对象的并发修改,但不允许这种修改时抛出的异常,例如有一个ArrayList集合,当检测到里面含有hello时,在hello的后面插入world:
这里写图片描述
此时就会抛出并发修改异常,这是因为在用迭代器进行遍历集合时同时在增加元素,需要注意的是,增强for循环底层也是用的迭代器,所以也不能在遍历是修改值,此时有两种方法解决这个问题:
一:使用ListIterator进行迭代
这里写图片描述

二:用get方法进行遍历:
这里写图片描述

### ConcurrentModificationException 异常的原因及解决方案 #### 异常原因 `java.util.ConcurrentModificationException` 是 Java 中的一种运行时异常,通常发生在使用迭代器(Iterator)遍历集合对象(如 `ArrayList`、`HashMap` 等)的过程中。当集合的结构被非迭代器自身的方法修改时(例如通过 `add` 或 `remove` 方法),就会抛出此异常[^2]。 这种异常的核心机制在于迭代器的 **fail-fast** 特性。在遍历过程中,迭代器会检查集合的修改计数器(`modCount`)是否与预期值(`expectedModCount`)一致。如果不一致,则说明集合在遍历过程中发生了结构上的修改,从而抛出 `ConcurrentModificationException`[^4]。 以下是异常检测源码的关键部分: ```java final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } ``` 上述代码展示了迭代器在每次调用 `next()` 方法时,都会执行 `checkForComodification()` 方法以确保集合未被并发修改。如果发现修改计数器不匹配,则立即抛出异常[^1]。 #### 解决方案 为避免 `ConcurrentModificationException`,可以采用以下几种方法: 1. **使用 Iterator 的 remove 方法** 在遍历集合时,应通过迭代器自身的 `remove()` 方法来移除元素,而不是直接调用集合的 `remove()` 方法。例如: ```java List<Integer> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { list.add(i); } Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) { Integer value = iterator.next(); if (value == 5) { iterator.remove(); // 使用迭代器的 remove 方法 } } ``` 2. **使用线程安全的集合类** 如果需要在多线程环境中操作集合,可以考虑使用线程安全的集合实现,例如 `CopyOnWriteArrayList` 或 `ConcurrentHashMap`。这些集合类通过内部机制保证了线程安全性,避免了 `ConcurrentModificationException` 的发生[^3]。 3. **使用同步块** 对于非线程安全的集合类,可以通过加锁的方式保护集合的访问和修改。例如: ```java List<Integer> list = Collections.synchronizedList(new ArrayList<>()); synchronized (list) { Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) { Integer value = iterator.next(); if (value == 5) { iterator.remove(); } } } ``` 4. **避免在增强 for 循环中修改集合** 增强 for 循环本质上也是基于迭代器实现的,因此在循环体内直接调用集合的 `remove()` 方法会导致异常。例如以下代码会抛出异常: ```java List<Integer> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { list.add(i); } for (Integer value : list) { // 增强 for 循环 if (value == 5) { list.remove(value); // 抛出 ConcurrentModificationException } } ``` 正确的做法是改用显式的迭代器进行操作。 #### 示例代码 以下是一个完整的示例,展示如何正确处理 `ConcurrentModificationException`: ```java import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { list.add(i); } // 正确方式:使用 Iterator 的 remove 方法 Iterator<Integer> iterator = list.iterator(); while (iterator.hasNext()) { Integer value = iterator.next(); if (value == 5) { iterator.remove(); // 安全移除 } } System.out.println(list); // 输出结果:[0, 1, 2, 3, 4, 6, 7, 8, 9] } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值