Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Android中处理ConcurrentModificationException_Java_Android_Exception_Arraylist - Fatal编程技术网

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
inside
onDraw()
函数。我的视图是一个
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;