【异常】——ConcurrentModificationException

前言

在对一个list进行循环,将其中一些元素从list中移除时:

在此之前先弄清楚一些相关的知识。

Fail-Fast机制

快速失败也就是fail-fast,它是Java集合的一种错误检测机制。

java.util包中的集合类都有 fail-fast 检测,如果fail-fast迭代器检测到在迭代过程中进行了更改操作,那么它会抛出 ConcurrentModificationException。

Fail-Safe机制

java.util.concurrent中的集合类都为fail-safe的,不会抛出ConcurrentModificationException异常

modCount

在java.util的集合类中,都包含这个属性

HashMap源码:

【异常】——ConcurrentModificationException_第1张图片

AbstractList源码:

【异常】——ConcurrentModificationException_第2张图片

表示集合结构上被修改的次数。(所有涉及结构变化的方法中,都增加了modCount的值)

下面举例ArrayList中部分函数源码:

添加:

【异常】——ConcurrentModificationException_第3张图片

移除:

【异常】——ConcurrentModificationException_第4张图片

清空:

【异常】——ConcurrentModificationException_第5张图片

 ConcurrentModificationException抛出

在集合内部迭代类中,还会有一个属性expectedModcount

ArrayList:

【异常】——ConcurrentModificationException_第6张图片

HashMap:

【异常】——ConcurrentModificationException_第7张图片

初始值都是等于modCount。

在内部迭代时涉及结构变化的方法中,都会判断expectedModCount是否等于modCount

【异常】——ConcurrentModificationException_第8张图片

【异常】——ConcurrentModificationException_第9张图片

 解决方法

单线程情况:

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

(2)建立一个集合,记录需要删除的元素,之后统一删除。

(3)不使用Iterator进行遍历,需要之一的是自己保证索引正常。

(4)使用并发集合类来避免ConcurrentModificationException,比如使用CopyOnArrayList,而不是ArrayList。

多线程情况:

(1)使用并发集合类,如使用ConcurrentHashMap或者CopyOnWriteArrayList。

你可能感兴趣的:(★★报错记录汇总★,★JAVA学习之路★)