【问题标题】:Handling Concurrent Modification Exception android处理并发修改异常android
【发布时间】:2015-07-21 12:16:38
【问题描述】:

我想避免并发修改异常。所以试图制作哈希图的副本。即使这样,它也会在从原始地图中删除元素时引发并发修改。下面是复制的代码,有没有错误?

private HashMap<String, ArrayList<String>> makeCopy(HashMap<String, ArrayList<String>> origMap) {

    HashMap<String, ArrayList<String>> copy=new HashMap<String, ArrayList<String>>();
    Iterator<String> iterator = origMap.keySet().iterator();

    while(iterator.hasNext()) {
        String key = iterator.next();
        copy.put(key,  new ArrayList<String>(origMap.get(key)));
    }
    return copy;
}

或者在try catch块中捕获后是否有可能处理它?

创建新副本的目的: 实际上 Hashmap 值的一个副本应该发送到另一个具有线程操作的活动(b),而原始副本将在调用另一个活动(b)的活动(A)中被修改,这就是为什么尝试创建哈希副本的原因不同参考的地图。

【问题讨论】:

  • 试试private synchronized HashMap&lt;String, ArrayList&lt;String&gt;&gt; makeCopy

标签: android hashmap concurrentmodification


【解决方案1】:

正如axierjhtjz所说,正确的做法是只让迭代器修改集合。

或者使用 ConcurrentHashMap。

一些好处:-->

当您的项目需要非常高的并发性时,您应该使用 ConcurrentHashMap。 它是线程安全的,无需同步整个地图。 使用锁完成写入时,读取可能会非常快。 在对象级别没有锁定。 锁定在哈希图存储桶级别的粒度要细得多。 如果一个线程尝试修改它而另一个线程正在迭代它,则 ConcurrentHashMap 不会抛出 ConcurrentModificationException。 ConcurrentHashMap 使用了大量的锁。

最后一点是什么可以帮助你:

如果一个线程尝试修改它而另一个线程正在对其进行迭代,则 ConcurrentHashMap 不会引发 ConcurrentModificationException。

详细阅读here

【讨论】:

    【解决方案2】:

    集合在迭代时不能同时修改(添加/删除)。您只能使用 iterator.remove() 来删除项目。否则会抛出 ConcurrentModificationException

    一个简单的解决方案是您可以使用简单的 for 循环(不要使用增强型 for 循环)而不是迭代器。

    【讨论】:

      【解决方案3】:

      使用 ConcurrentHashmap 代替 Hashmap 或获取同步映射以读取值 https://developer.android.com/reference/java/util/concurrent/ConcurrentHashMap.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-19
        • 2013-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多