java 如何在 Android 中处理 ConcurrentModificationException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6621991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to handle ConcurrentModificationException in Android
提问by dinesh707
Im trying to delete item from a ArrayList. Some timesit pops an exception, "java.util.ConcurrentModificationException".
我正在尝试从 ArrayList 中删除项目。有时它会弹出一个异常,“java.util.ConcurrentModificationException”。
First i tried to remove them by array_list_name.remove(i), but it failed and some people were asked to use Iterator instead. So my current code is as follows.
首先,我尝试通过 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;
}
}
And i call "array_list_name" inside onDraw() function in view. my view is a SurfaceView. Can any one suggest me how to delete items from ArrayList without getting this error.
我在视图中调用 onDraw() 函数中的“array_list_name”。我的观点是 SurfaceView。任何人都可以建议我如何从 ArrayList 中删除项目而不会出现此错误。
采纳答案by Murat Can ALPAY
Try using java.util.concurrent.CopyOnWriteArrayList
instead of ArrayList
尝试使用java.util.concurrent.CopyOnWriteArrayList
代替ArrayList
回答by Bjarke Freund-Hansen
Seems from the comments that your ArrayList<Collectable>
is accessed from the onDraw()
method in one thread, by the UI, concurrently with you removing items from it in another thread.
从评论看来,您ArrayList<Collectable>
是从onDraw()
一个线程中的方法访问的,由 UI 访问,同时您在另一个线程中从中删除项目。
So, why not just wrap both accessors in a
那么,为什么不将两个访问器包装在一个
synchronized(array_list_name)
{
// UI access code or item removal code
}
Note that this might make your UI laggy if removing items takes a long time. If this is the case, consider making a list of all item indexes to be removed, and remove them in a tight synchronized loop after iterating over the whole list.
请注意,如果删除项目需要很长时间,这可能会使您的 UI 滞后。如果是这种情况,请考虑制作一个包含要删除的所有项目索引的列表,并在遍历整个列表后在紧密的同步循环中删除它们。
Update
更新
It seems to me your whole code snippet could be simplified to just:
在我看来,您的整个代码片段可以简化为:
synchronized(array_list_name)
return array_list_name.remove(id);
回答by oguzhan
Have you ever thought to use Vector List? If you need a thread-safe implementation, you should use Vectorinstead of ArrayList. Vectorlist's usage is same with ArrayList. Just change its type with Vector.
你有没有想过使用矢量列表?如果您需要线程安全的实现,则应使用Vector而不是ArrayList。 向量列表的用法与ArrayList相同。只需使用Vector更改其类型即可。
Unsafe usage
不安全使用
ArrayList<FutureTask> futureTasks;
Change with
换用
Vector<FutureTask> futureTasks;
That's all.
就这样。
回答by Tim Büthe
You could create a defensive copy of the list like so:
您可以像这样创建列表的防御副本:
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;
}
}