java.util.ConcurrentModificationException 解决 Android
16lz
2022-04-03
java.util.ConcurrentModificationException 解决 Android java
在项目里面 遇到了这个bug :
E/AndroidRuntime(22055): java.util.ConcurrentModificationException E/AndroidRuntime(22055): at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
查看了下 这个异常介绍:
[java] view plain copy
- AnConcurrentModificationExceptionisthrownwhenaCollectionismodifiedandanexistingiteratorontheCollectionisusedtomodifytheCollectionaswell.
ConcurrentModificationException 抛出的条件 大意是:一个迭代器在迭代集合的时候 集合被修改了
举个通俗的栗子
例如 在迭代 Arraylist 的时候 对Arraylist进行增删操作 就会抛出该异常分析原因:
集合中list set 等 都没有实现同步 , 在多线程中 对集合进行操作时 同步操作都是由外部进行控制再来看一下 Iterator 的工作原理 [java] view plain copy
- Aniteratoroverasequenceofobjects,suchasacollection.
- Ifacollectionhasbeenchangedsincetheiteratorwascreated,methodsnextandhasNext()maythrowaConcurrentModificationException.Itisnotpossibletoguaranteethatthismechanismworksinallcasesofunsynchronizedconcurrentmodification.Itshouldonlybeusedfordebuggingpurposes.Iteratorswiththisbehaviorarecalledfail-fastiterators.
- ImplementingIterableandreturninganIteratorallowsyourclasstobeusedasacollectionwiththeenhancedforloop.
翻译是 如果集合已经改变自创建迭代器,next和hasNext方法()可能抛出ConcurrentModificationException。这是不可能的,以保证这一机制的工作中不同步并发修改的所有情况。它应该只用于调试的目的。迭代器与这种行为被称为快速失败的迭代器。
按照Iterator的工作原理 应该是在一个独立线程里面完成 且Iterator 执行的时候 迭代的对象必须是不可变的 单向的 顺序的
来看看实际解决方案:
1) 在需要迭代的时候 增加一个 锁
但是比较影响效率2) 每次前迭代 将集合复制一遍
Arraylist 里面有个toarray()方法 [java] view plain copy
- /**
- *Returnsanewarraycontainingallelementscontainedinthis
- *{@codeArrayList}.
- *
- *@returnanarrayoftheelementsfromthis{@codeArrayList}
- */
- @OverridepublicObject[]toArray(){
- ints=size;
- Object[]result=newObject[s];
- System.arraycopy(array,0,result,0,s);
- returnresult;
- }
toArray() 方法 会调用 System.arraycopy( array, 0, result, 0, s); 将集合copy一遍
在多线程 当我需要迭代Arraylist的时候 在集合后面增加一个 toArray() 将集合复制一遍 . 这样对原集合进行的修改操作并不会影响到copy后的新集合
每日前进一步
转载请注明 http://blog.csdn.net/aaawqqq/article/details/43884623
多有不足 希望和大家有更多交流 谢谢
更多相关文章
- ‘void android.view.View.dispatchDetachedFromWindow() on a n
- android使用ksoap2-android调用webservice时报java.io.EOFExcept
- 在四大主件以外的类中 怎么使用Context
- android SQLiteOpenHelper 对SQLite的操作
- Android学习笔记4——Activity的生命周期
- android最近任务列表,删除某个应用操作
- android listview 长按弹出菜单--ContextMenu并进行删除操作
- Android(安卓)检测用户一段时间无操作
- Android(安卓)PrecomputedTextCompat