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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:40:17  来源:igfitidea点击:

How to handle ConcurrentModificationException in Android

javaandroidexception-handlingarraylist

提问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.CopyOnWriteArrayListinstead 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;
   }
}