java.util.ConcurrentModificationException 解决 Android

java.util.ConcurrentModificationException 解决       Android  java


在项目里面 遇到了这个bug :


E/AndroidRuntime(22055): java.util.ConcurrentModificationException
E/AndroidRuntime(22055):      at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)


查看了下 这个异常介绍:

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后的新集合   


每日前进一步

转载请注明  http://blog.csdn.net/aaawqqq/article/details/43884623

多有不足
希望和大家有更多交流
谢谢




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。