0 什么情况下会出现ConcurrentModificationException异常?
ConcurrentModificationException继承自RuntimeException;
在使用迭代器或者增强for循环(底层也是利用的迭代器)遍历的时候,使用集合的增删改方法对集合进行更新操作的时候会出现这个异常;
1
2
3
4
5
6
7
8
9
10
List<Integer> list = new LinkedList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
for (int x : list) {
if (x == 2) {
list.remove(x);
}
}
异常代码:
1
2
3
4
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:966)
at java.util.LinkedList$ListItr.next(LinkedList.java:888)
at Main.main(Main.java:18)
1 ConcurrentModificationException出现原因分析
迭代器的next方法:
每次执行next()的时候都会先进行一次校验,校验的是List的修改次数,迭代器对象有一个变量记录了list的期望修改次数(只有通过迭代器修改才会变更这个数值),List本身也有一个记录修改次数的变量,迭代器在迭代的时候,会先判断迭代器期望的修改次数和list本身的修改次数是否一致,如果不一致就报错;
2 如何避免ConcurrentModificationException异常?
- 普通for循环
- 直接使用迭代器
- 使用stream()流处理过滤
- Collection.removeIf()
- 使用CopyOnWriteArrayList并发安全的数据结构