【异常】——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源码:

AbstractList源码:

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

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

添加:

移除:

清空:

 ConcurrentModificationException抛出

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

ArrayList:

HashMap:

初始值都是等于modCount。

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

 解决方法

单线程情况:

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

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

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

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

多线程情况:

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

发布了74 篇原创文章 · 获赞 960 · 访问量 72万+

猜你喜欢

转载自blog.csdn.net/qq_37141773/article/details/99307038
今日推荐