java中的ConcurrentModificationException是什么异常?在哪些场景下会报该异常?

在软件构造实验Lab2的ConcreteVerticesGraph里,需要我们编写remove()方法。移除一个点没有别的方法,只有遍历集合vertices(),找到该点并移除。

 

 当时我没有写上红框中的break,出现了ConcurrentModificationException的报错。写实验时没有仔细深究,上网搜索也没有看明白,写出break也是机缘巧合下想到了,后来搜索资料,详细地了解了一下这个报错。

异常简介

ConcurrentModificationException是基于java集合中的 快速失败(fail-fast) 机制产生的,在使用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了增删改,就会抛出该异常。
快速失败机制使得java的集合类不能在多线程下并发修改,也不能在迭代过程中被修改。

抛出异常的原因

在实验中,我们使用ArrayList的remove方法遍历并移除元素。

此时会抛出异常:
Exception in thread “main” java.util.ConcurrentModificationException

参考ArrayList的源码中关于remove的片段

 1 public void remove() {
 2             if (lastRet < 0)
 3                 throw new IllegalStateException();
 4             checkForComodification();
 5 
 6             try {
 7                 ArrayList.this.remove(lastRet);
 8                 cursor = lastRet;
 9                 lastRet = -1;
10                 expectedModCount = modCount;
11             } catch (IndexOutOfBoundsException ex) {
12                 throw new ConcurrentModificationException();
13             }
14         }
15 final void checkForComodification() {
16             if (modCount != expectedModCount)
17                 throw new ConcurrentModificationException();
18         }

remove会检测是否有修改,判断依据为modCount != expectedModCount,每当变更列表,都会改变modCount的值,如果检测到modCount != expectedModCount,那么就会抛出Concurrent Modification Exception。
foreach循环遍历集合,实际上隐式调用了迭代器遍历,同样调用集合的remove或add等方法会抛异常;

解决方案

1.使用Iterator提供的remove方法,用于删除当前元素。

 

 2.新建一个集合存放要删除的元素,之后统一删除。

 

 3.不使用iterator遍历,但是这里要注意移除了一个元素,索引i也随之改变。

 

 

参考博客:

https://blog.csdn.net/weixin_40807247/article/details/88413347?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-1-88413347-blog-79559814.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-1-88413347-blog-79559814.pc_relevant_default&utm_relevant_index=2

https://blog.csdn.net/leeafay/article/details/79559814?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-79559814-blog-81485867.pc_relevant_paycolumn_v3&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-79559814-blog-81485867.pc_relevant_paycolumn_v3&utm_relevant_index=1

posted @ 2022-06-01 09:29  小兔巴尼  阅读(670)  评论(0编辑  收藏  举报