Java 如何在Android中处理ConcurrentModificationException
我正试图从Java 如何在Android中处理ConcurrentModificationException,java,android,exception,arraylist,Java,Android,Exception,Arraylist,我正试图从ArrayList中删除项目。有时它会弹出一个异常,java.util.ConcurrentModificationException 首先,我试图通过array\u list\u name.remove(I)删除它们,但失败了,一些人被要求使用迭代器。因此,我目前的代码如下: for (Iterator<Collectable> iter = array_list_name.iterator(); iter.hasNext();) { Collectable s =
ArrayList
中删除项目。有时它会弹出一个异常,java.util.ConcurrentModificationException
首先,我试图通过array\u list\u name.remove(I)
删除它们,但失败了,一些人被要求使用迭代器。因此,我目前的代码如下:
for (Iterator<Collectable> iter = array_list_name.iterator(); iter.hasNext();) {
Collectable s = iter.next();
if (s.equals(array_list_name.get(id))){
iter.remove();
return true;
}
}
for(迭代器iter=array_list_name.Iterator();iter.hasNext();){
可收集的s=iter.next();
if(s.equals(数组\列表\名称.get(id))){
iter.remove();
返回true;
}
}
我在视图中调用
array\u list\u name
insideonDraw()
函数。我的视图是一个SurfaceView
。有人能建议我如何从ArrayList
中删除项目而不出现此错误吗?您可以创建列表的防御性副本,如下所示:
List copy = new ArrayList(array_list_name);
for (Iterator<Collectable> iter = copy.iterator(); iter.hasNext();) {
Collectable s = iter.next();
if (s.equals(copy.get(id))){
iter.remove();
return true;
}
}
List copy=newarraylist(数组列表名称);
for(迭代器iter=copy.Iterator();iter.hasNext();){
可收集的s=iter.next();
如果(s.equals(copy.get(id))){
iter.remove();
返回true;
}
}
尝试使用java.util.concurrent.CopyOnWriteArrayList
而不是ArrayList从注释中可以看出,用户界面在一个线程中通过onDraw()
方法访问您的ArrayList
,同时在另一个线程中从中删除项目
那么,为什么不将两个访问器都包装在一个
synchronized(array_list_name)
{
// UI access code or item removal code
}
请注意,如果删除项目需要很长时间,这可能会使您的UI滞后。如果是这种情况,请考虑将要删除的所有项索引列表,并在遍历整个列表之后以紧密同步的循环将它们移除。
更新
在我看来,您的整个代码片段可以简化为:
synchronized(array_list_name)
return array_list_name.remove(id);
你有没有想过用它?如果需要线程安全的实现,应该使用Vector
而不是ArrayList
。
Vector
列表的用法与ArrayList
相同。只需使用Vector
更改其类型即可
不安全使用
ArrayList未来任务;
改变
矢量未来任务;
仅此而已。我不清楚问题所在-您实际使用了iter.remove()
并查看CME,但不总是这样,有时会这样?CME=java.util.ConcurrentModificationExceptionary当迭代器处于活动状态时,是否有其他线程访问ArrayList?是,onDraw
在UI线程中被调用,因此它可能与另一个线程中的项目移除同时被调用。这就是问题所在,请参阅:如果在迭代过程中修改了基础集合,则迭代器的行为未指定…
我只建议如果修改很少,否则手动复制会更好。但这会删除副本中的元素。询问者可能希望删除数组\u列表\u name
中的元素。如果按其索引将其删除,则无法确定是否获得了正确的元素,因为列表可能已更改。这是迄今为止该线程的最佳答案。使用一个名为Vector
的类(该类专门用于并发使用)是正确的解决方案。我已经在我自己的项目中使用过,在那里我遇到了类似的问题,并且得到了ConcurrentModificationException
s。谢谢!
ArrayList<FutureTask> futureTasks;
Vector<FutureTask> futureTasks;