首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ConcurrentModificationException与WeakHashMap

ConcurrentModificationException与WeakHashMap
EN

Stack Overflow用户
提问于 2013-08-06 00:00:40
回答 4查看 1.5K关注 0票数 1

我有下面的代码,但是我得到了ConcurrentModificationException,我应该如何避免这个问题?(出于某种原因,我不得不使用WeakHashMap )

代码语言:javascript
复制
WeakHashMap<String, Object> data = new WeakHashMap<String, Object>();

 // some initialization code for data

  for (String key : data.keySet()) {
        if (data.get(key) != null && data.get(key).equals(value)) {
            //do something to modify the key
        } 
    }
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-08-06 02:29:55

可能是因为迭代中的// do something实际上正在修改底层集合。

来自ConcurrentModificationException

例如,如果线程在使用失败快速迭代器迭代集合时直接修改集合,迭代器将抛出此异常。

来自(弱)HashMap的keySet()

返回此映射中包含的键的集合视图。集合由映射支持,因此对映射的更改反映在集合中,反之亦然。如果映射是在集合上的迭代正在进行时被修改的(除非通过迭代器自己的移除操作),则迭代的结果是未定义的。

票数 -2
EN

Stack Overflow用户

发布于 2020-01-29 05:22:40

用于WeakHashMap的Javadoc类解释了为什么会发生这种情况:

映射不变量不适用于这个类。因为垃圾收集器可以在任何时候丢弃键,所以WeakHashMap的行为可能就像一个未知的线程正在悄悄地删除条目一样。

此外,您使用的增强型for-循环在引擎盖下生成的迭代器具有快速失败的类型,正如javadoc中引用的解释所示。

由这个类的所有“集合视图方法”返回的集合的迭代器返回的迭代器都是失败的:如果在创建迭代器之后的任何时候对映射进行了结构上的修改,那么除非通过迭代器自己的remove方法,否则迭代器将抛出一个ConcurrentModificationException。因此,在并发修改的情况下,迭代器会迅速而干净地失败,而不是在未来某个未定的时间冒着任意的、不确定的行为的风险。

因此,由于以下原因,循环可以抛出此异常:

  1. 垃圾收集器已经删除了键集中的一个对象。
  2. 代码之外的东西在映射中添加了一个对象。
  3. 循环内部发生了修改。

由于您的意图似乎是处理尚未被GC处理的对象,我建议使用迭代器如下:

代码语言:javascript
复制
Iterator<String> it = data.keySet().iterator();
int count = 0;
int maxTries = 3;
while(true) {
    try {
        while (it.hasNext()) {
            String str = it.next();
            // do something
        }
        break;
    } catch (ConcurrentModificationException e) {
        it = data.keySet().iterator(); // get a new iterator
        if (++count == maxTries) throw e;
    }
}
票数 2
EN

Stack Overflow用户

发布于 2021-02-11 01:51:15

您可以先克隆密钥集,但请注意,在此之后保存强引用:

代码语言:javascript
复制
Set<KeyType> keys;
while(true) {
   try {
       keys = new HashSet<>(weakHashMap.keySet());
       break;
   } catch (ConcurrentModificationException ignore) {
   }
}

for (KeyType key : keys) {
    // ...
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18069750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档