前言

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

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

Fail-Fast机制

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

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

Fail-Safe机制

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

modCount

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

HashMap源码:

20190812163308315.png

AbstractList源码:

20190812163417545.png

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

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

添加:

20190812163734587.png

移除:

20190812163858880.png

清空:

20190812163932548.png

ConcurrentModificationException抛出

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

ArrayList:

20190812164620801.png

HashMap:

201908121647079.png

初始值都是等于modCount。

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

111.png

20190812165233431.png

解决方法

单线程情况:

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

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

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

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

多线程情况:

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


版权声明:文章转载请注明来源,如有侵权请联系博主删除!
最后修改:2019 年 12 月 25 日 11 : 53 AM
如果觉得我的文章对你有用,请随意赞赏
评论打卡也可以哦,您的鼓励是我最大的动力!