ArrayList foreach循环增添删除导致ConcurrentModificationException解决分析
一、使用背景
在阿里巴巴开发手册中,有这样一条规定:不要在foreach循环里进行add和remove操作(这里指的是List的add和remove操作),
否则会抛出ConcurrentModificationException。remove元素请使用iterator。

二、源码
1.我们知道foreach是语法糖,他本质还是iterator进行的循环,因此下面的代码和使用foreach循环是一样的。
在循环里面我们使用“错误”操作,使用List的add方法进行操作,会抛出ConcurrentModificationException
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("apple");
Iterator<String> iterator = arrayList.iterator();
while(iterator.hasNext()){
String value = iterator.next();
if("apple".equals(value)){
arrayList.add("orange");
}
}三、源码解析
1.arrayList.iterator();
①返回Itr类,并将modcount的值赋值给一个变量expectedModCount,其中modcount表示List实际被增删的次数,expectedModCount表示该迭代器期望被增删的次数,当新建Itr类的时候会给他赋初始值,只有通过该迭代器进行值的增删才会修改该值


2.iterator.next();
①在调用迭代器的next方法时,他会进行检查,比较modCount和expectedModCount的值,如果不相等,Concurrent


总结
1.modCount和expectedModeCount不一致才会抛出ConcurrentModificationException。当我们调用List的remove方法时,他只会修改modCount的值;当我们调用iterator的remove方法,他会将modCount的值赋值给expectedModeCount
2.modCount和expectedModeCount是属于fast-fail机制,用于多线程中,当进行遍历的时候,有其他线程修改值的时候就会进行检查
解决方法
- 1.使用普通for循环进行操作
- 2.在循环中使用iterator进行操作
- 3.使用stream流进行过滤
- 4.使用fast-saft安全的类,如ConCurrentLinkedQueue
以上就是ArrayList foreach循环增添删除导致ConcurrentModificationException解决分析的详细内容,更多关于ArrayList foreach循环的资料请关注脚本之家其它相关文章!
相关文章
spring boot使用RabbitMQ实现topic 主题
本篇文章主要介绍了spring boot使用RabbitMQ实现topic 主题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-03-03
教你使用idea搭建ssm详细教程(Spring+Spring Mvc+Mybatis)
今天教大家使用idea搭建ssm详细教程(Spring+Spring Mvc+Mybatis),文中有非常详细的图文介绍及代码示例,对正在学习使用idea的小伙伴很有帮助,需要的朋友可以参考下2021-05-05


最新评论