【问题标题】:ConcurrentModificationException Program in java HashMapjava HashMap中的ConcurrentModificationException程序
【发布时间】:2023-04-09 19:37:01
【问题描述】:

代码:

Map<Integer,DealCountUpdater> dealCountMap=new HashMap<Integer,DealCountUpdater>();

public void update(){
    for(Map.Entry<Integer, DealCountUpdater> e:new HashMap<Integer,DealCountUpdater>(dealCountMap).entrySet()){//line:58
        System.out.println(e.hashCode());
    }
}

当我运行这段代码时,得到以下异常:

java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
        at java.util.HashMap$EntryIterator.next(HashMap.java:834)
        at java.util.HashMap$EntryIterator.next(HashMap.java:832)
        at java.util.HashMap.putAllForCreate(HashMap.java:435)
        at java.util.HashMap.<init>(HashMap.java:225)
        at org.my.tuan.count.CountUpdater.update(CountUpdater.java:58)
        at org.my.tuan._Maintainer.run(TuanSched.java:110)

这一行是 CountUpdater.java:58 :

for(Map.Entry<Integer, DealCountUpdater> e:new HashMap<Integer,DealCountUpdater>(dealCountMap).entrySet()){

我在谷歌上搜索了这个程序,我知道我可以使用ConcurrentHashMap 而不是普通的HashMap

但我想知道,我为什么要使用:

new HashMap<Integer,DealCountUpdater>(dealCountMap)

为HashMap创建新的Instance,还是抛出ConcurrentModificationException

如何不使用ConcurrentHashMap 来解决它?

感谢您的帮助:)

【问题讨论】:

  • 你漏掉了最重要的部分,也就是//updating...代表的代码。我们不是通灵者。请将代码添加到帖子中。另外,您的程序是多线程的吗?是否有其他活动可以改变源映射?
  • 求帮助,这个异常在 CountUpdater.java:58 处抛出,这一行在:for(Map.Entry&lt;Integer, DealCountUpdater&gt; e:new HashMap&lt;Integer,DealCountUpdater&gt;(dealCountMap).entrySet()){ ,我在我的问题中添加了它,//updating... 无关紧要

标签: java multithreading java.util.concurrent


【解决方案1】:

原因是这样的:

  1. 您通过在其构造函数中传递另一个 hashmap(H2) 来创建一个新的 hashmap(H1)。
  2. 在 H1 的构造函数中,它尝试遍历 H2 的元素,以添加自身。
  3. 当第 2 步中的迭代正在进行时,其他一些线程修改了 H2。因此 ConcurrentModificationException

不使用ConcurrentHashMap如何解决?

  1. 做外部同步
  2. here 所述,使用copy-n-write 映射。

但我仍然建议使用 ConcurrentHashMap,除非你真的有你的理由。

【讨论】:

  • 你能举一个 ConcurrentHaspMap is above 场景的工作示例吗?
【解决方案2】:

当另一个线程正在对其进行迭代时,您根本不能或不应该修改线程中的哈希图。在这种情况下,HashMap 迭代器将抛出 ConcurrentModificationException。这被称为迭代器的“快速失败”行为,因为它在 java 文档中明确提到。对您来说最好的解决方案是使用 ConcurrentHashMap。如果您不想使用那个,那么您必须取消多线程。正如吉姆指出的那样,如果您可以提供有关多线程的更多详细信息,那么您可能会得到更好的解决方案。另外,为什么你不想使用 ConcurrentHashMap?有什么特别的原因吗?

【讨论】:

    猜你喜欢
    • 2015-09-23
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    相关资源
    最近更新 更多