java.util.ConcurrentModificationException 异常的解决方法
发布日期:2021-06-29 21:09:22 浏览次数:2 分类:技术文章

本文共 1245 字,大约阅读时间需要 4 分钟。

1 发现问题

在迭代 Set 的过程中,删除了其中的某个元素,这时系统会抛出 ConcurrentModificationException 异常。

代码如下:

Set
activeActivityNames = findActiveActivityNames(businessId);for (CanRollBackActivity activity : data) { if (activeActivityNames.contains(activity.getActivityName())) { data.remove(activity); }}

2 分析问题

我们先来看看这个 ConcurrentModificationException 类。

当方法检测到对象正在进行并发修改,但实际又不允许这种修改时,就会抛出此异常。

例如,某个线程在 Collection 上进行迭代时,通常不允许另一个线性修改该这个 Collection。通常在这些情况下,迭代的结果是不确定的。如果检测到这种行为,一些迭代器的实现(包括 JRE 提供的所有通用 collection 实现)可能会选择抛出此异常。执行抛出异常操作的迭代器称为快速失败 迭代器,因为迭代器很快就会失败,而不会出现在将来的某个时间上发生不确定行为的风险。

注意,迭代器的快速失败行为无法得到保证,因为不可能对是否出现不同步的并发修改做出任何硬性的保证。快速失败操作会尽最大努力抛出 ConcurrentModificationException。因此,为提高此类操作的正确性而编写一个依赖于此异常的程序是错误的做法,正确做法是:ConcurrentModificationException 应该仅用于检测 bug。

我们在代码中使用了一个 Set(Collection 的一种),然后在迭代的过程中删除了其中的某个元素,所以自然会抛出 ConcurrentModificationException 异常咯。

3 解决方法

使用 Iterator 的 remove 方法。这个方法会从迭代器指向的 collection 中移除迭代器返回的最后一个元素。

注意:每次调用 next 只能调用一次此方法。如果进行迭代时用调用此方法之外的其他方式修改了该迭代器所指向的 collection,则迭代器的行为是不确定的。

修复后的代码:

Iterator
iterator = data.iterator();while (iterator.hasNext()) { CanRollBackActivity activity = iterator.next(); if (activeActivityNames.contains(activity.getActivityName())) { iterator.remove(); }}

转载地址:https://deniro.blog.csdn.net/article/details/79023544 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:“ORA-01791:不是SELECTed表达式” 问题的解决方法
下一篇:手把手教你把基于 eclipse 的项目转换为基于 idea 的项目

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月16日 03时41分05秒