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循环的资料请关注脚本之家其它相关文章!
相关文章
SpringBoot整合Spring Security构建安全的Web应用
pring Security是一个强大的身份验证和访问控制框架,本文主要介绍了SpringBoot整合Spring Security构建安全的Web应用,具有一定的参考价值,感兴趣的可以了解一下2024-01-01logback EvaluatorFilter日志过滤器源码解读
这篇文章主要为大家介绍了logback EvaluatorFilter日志过滤器源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-11-11
最新评论