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也随之改变。
参考博客:
最新文章
- 绘制扇形效果线条小Bug解决
- C++ 生成 dll 和调用 dll 的方法实例(转)
- 定时备份mysql
- BZOJ-1477 青蛙的约会 拓展欧几里德
- Android SDK无法更新解决方法
- JedisPool连接池实现难点
- cdev_系列函数
- Cannot generate SSPI context---MS SQL ERROR
- 组件局域网中的无集线器、Windows XP、Windows 7、Windows 8的对等网
- 《JS权威指南学习总结--1.1语言核心》
- yum 安装Apache
- Android Gradle Task
- Idea快捷键和使用技巧【未完】
- Java基础实训2
- Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)
- Spark记录-官网学习配置篇(二)
- mongoose实现批量删除和多id查询的api/方法
- Confluence 6 LDAP 连接池配置参数
- 【渗透测试学习平台】 web for pentester -4.目录遍历
- Cat VS Dog---hdu3829(最大独立集)