如何在Android中处理ConcurrentModificationException

时间:2011-07-08 08:41:05

标签: java android exception-handling arraylist

我试图从ArrayList中删除项目。 有时会弹出异常,“java.util.ConcurrentModificationException”。

首先我尝试通过array_list_name.remove(i)删除它们,但它失败了,有些人被要求使用Iterator。所以我目前的代码如下。

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;
   }
}

我在视图中的onDraw()函数中调用“array_list_name”。我的观点是SurfaceView。任何人都可以建议我如何从ArrayList中删除项目而不会收到此错误。

4 个答案:

答案 0 :(得分:7)

尝试使用java.util.concurrent.CopyOnWriteArrayList代替ArrayList

答案 1 :(得分:6)

从评论中可以看出,您的ArrayList<Collectable>是通过UI在一个线程中从onDraw()方法访问的,与您在另一个线程中从中删除项目同时进行访问。

那么,为什么不将两个访问器包装在

synchronized(array_list_name)
{
    // UI access code or item removal code
}

请注意,如果删除项目需要很长时间,这可能会导致UI滞后。如果是这种情况,请考虑列出要删除的所有项目索引,并在迭代整个列表后在紧密同步循环中删除它们。

<强>更新

在我看来,您的整个代码段可以简化为:

synchronized(array_list_name)
    return array_list_name.remove(id);

答案 2 :(得分:0)

您可以像这样创建列表的防御性副本:

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;
   }
}

答案 3 :(得分:0)

您有没有想过使用Vector List?如果您需要线程安全实现,则应使用 Vector 而不是 ArrayList 矢量列表的用法与 ArrayList 相同。只需使用矢量更改其类型。

  

不安全的使用

ArrayList<FutureTask> futureTasks;
  

更改
Vector<FutureTask> futureTasks;

这就是全部。