java.util.ConcurrentModificationException at java.util.ArrayList$ArrayListIterator.next(ArrayList.
来源:互联网 发布:java 开发支付流程 编辑:程序博客网 时间:2024/05/17 21:51
java.util.ConcurrentModificationException at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)的解决
在项目里面 遇到了这个bug :
java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
at com.wanyue.tool.CleanActivity.clean(CleanActivity.java:149)
查看了下 这个异常介绍:
An ConcurrentModificationException is thrown when a Collection is modified and an existing iterator on the Collection is used to modify the Collection as well.
ConcurrentModificationException 抛出的条件 大意是: 一个迭代器在迭代集合的时候 集合被修改了
举个通俗的栗子
例如 在迭代 Arraylist 的时候 对Arraylist进行增删操作 就会抛出该异常
分析原因:
集合中 list set 等 都没有实现同步 , 在多线程中 对集合进行操作时 同步操作都是由外部进行控制
再来看一下 Iterator 的工作原理
An iterator over a sequence of objects, such as a collection.If a collection has been changed since the iterator was created, methods next and hasNext() may throw a ConcurrentModificationException. It is not possible to guarantee that this mechanism works in all cases of unsynchronized concurrent modification. It should only be used for debugging purposes. Iterators with this behavior are called fail-fast iterators.Implementing Iterable and returning an Iterator allows your class to be used as a collection with the enhanced for loop.
翻译是
如果集合已经改变自创建迭代器,next和hasNext方法()可能抛出ConcurrentModificationException。这是不可能的,以保证这一机制的工作中不同步并发修改的所有情况。它应该只用于调试的目的。迭代器与这种行为被称为快速失败的迭代器。
按照Iterator的工作原理 应该是在一个独立线程里面完成 且Iterator 执行的时候 迭代的对象必须是不可变的 单向的 顺序的
来看看实际解决方案:
1) 在需要迭代的时候 增加一个 锁
但是比较影响效率
2) 每次前迭代 将集合复制一遍
Arraylist 里面有个toarray()方法
/** * Returns a new array containing all elements contained in this * {@code ArrayList}. * * @return an array of the elements from this {@code ArrayList} */ @Override public Object[] toArray() { int s = size; Object[] result = new Object[s]; System.arraycopy(array, 0, result, 0, s); return result; }
toArray() 方法 会调用 System.arraycopy(array, 0, result, 0, s); 将集合copy一遍
在多线程 当我需要迭代Arraylist的时候 在集合后面增加一个 toArray() 将集合复制一遍 .
这样对原集合进行的修改操作并不会影响到copy后的新集合
在迭代时对原集合调用一下xx.toArray();方法即可。
特此记录一下。欢迎交流。
- java.util.ConcurrentModificationException at java.util.ArrayList$ArrayListIterator.next(ArrayList.
- at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576)
- java.util.ConcurrentModificationException at java.util.ArrayList
- 解决ArrayList的java.util.ConcurrentModificationException
- arraylist 遇到java.util.ConcurrentModificationException真正原因。
- ArrayList 的java.util.ConcurrentModificationException异常?
- java.util.ArrayList学习
- java.util.ArrayList
- JAVA.Util.ArrayList
- java.util.ArrayList size()
- 【源代码】java.util.ArrayList
- 11 java.util.ArrayList
- java.util.ArrayList 源码
- Java-Util之ArrayList
- java.util.ArrayList<E>
- java.util.ArrayList
- java.util.ArrayList
- java.util.ArrayList
- Access Log Sampler之Jemeter
- A+B problem(64bit Integer + EOF)
- maven编译项目时出错(2)
- gulp 搭建项目
- Java 数字千位分隔符
- java.util.ConcurrentModificationException at java.util.ArrayList$ArrayListIterator.next(ArrayList.
- Java单例模式能否通过反射改变静态属性对象
- Kotlin学习(一)基础语法
- Android中Dalvik和Art的认识和区别
- LeetCode | 2. Add Two Numbers
- MYSQL数据库(八)- 修改数据表添加约束
- kindeditor引入Java程序遇到的问题
- 量亿数据告诉你量化交易的魅力
- 理解RESTful架构