【问题标题】:ConcurrentModificationException when I do a addAll for a Set [duplicate]当我为 Set 执行 addAll 时出现 ConcurrentModificationException [重复]
【发布时间】:2020-11-30 16:13:14
【问题描述】:

在下面的代码中,allStates.addAll(states) 出现了 concurrentModificationException。我怎样才能避免这种情况?

public synchronized Set<String> getAllStates(String clientName, Map<String, Set<String>> allClientStates) {
    Set<String> allStates = new ConcurrentSkipListSet<>();
    final Set<String> keySet = allClientStates.keySet();
    for(String key: keySet) {
      Set<String> states = allClientStates.get(key);
      if(states != null)
        allStates.addAll(states);
    }
    return allStates;
  }

这是堆栈跟踪的顶部

exception": "null\njava.util.ConcurrentModificationException\n\tat java.util.HashMap$HashIterator.nextNode(HashMap.java:1445)\n\tat java.util.HashMap$KeyIterator.next(HashMap.java:1469)\n\tat java.util.AbstractCollection.addAll(AbstractCollection.java:343)\n\tat com.xxx.config.ClientDashboardConfig.getAllStates(ClientDashboardConfig.java:312)

【问题讨论】:

  • 您似乎正在其他地方修改地图。另请注意,似乎根本没有使用密钥的理由:allClientStates.valueSet().stream().flatMap(Set::stream).collect(toSet())
  • 尝试使用基本的Set 类型,例如HashSet 而不是ConcurrentSkipListSet。我认为问题的一部分是代码运行得太快,并且您在对象上同时执行了多个 allAll 方法。 HashSet 应该可以解决问题。
  • 这个项目使用的是 Java 8,因此我用这段代码更新了这篇文章 allClientStates.values() .stream() .flatMap(Set::stream) .collect(Collectors.toSet());
  • 嘿伙计,如果我的回答解决了您的问题,请继续接受。这个网站是在志愿者的努力下运行的,至少你能做的就是感谢人们的时间。
  • 进行上述更改后仍然出现concurrentModificationException异常。

标签: java concurrentmodification


【解决方案1】:
allClientStates.values().stream()
    .flatMap(keys -> keys.stream())
    .collect(Collectors.toSet());

【讨论】:

  • 这并不能解决问题。将代码修改为The current answers don't solve the problem. I changed my code to Set allStates = allClientStates.values().stream().flatMap(Set::stream).collect(Collectors.toSet()); 后我仍然得到 ConcurrentModificatinoException ```我仍然得到异常````
【解决方案2】:

我不明白为什么需要 ConcurrentSkipListSet 和 clientName。这段代码是否完整?

也不清楚是否有JVM版本限制

使用 java 8 你可以这样做:

allClientStates.values()
.stream()
.flatMap(Collection::stream)
.collect(Collectors.toSet());

【讨论】:

  • 在发布之前,我正在尝试并从该函数中删除了一些其他不相关的代码。因此,您会看到 ConcurrentSkipListSet 和未使用的参数。我会试试你的建议。
  • 这并不能解决问题。将代码修改为The current answers don't solve the problem. I changed my code to Set allStates = allClientStates.values().stream().flatMap(Set::stream).collect(Collectors.toSet()); 后我仍然得到 ConcurrentModificatinoException ```我仍然得到异常````
  • @DeepakGopal 能否提供一个参数示例以便我重现该问题?
  • ``` final Set>> entrySet = allClientStates.entrySet(); for(Map.Entry> key: entrySet) { Set states = key.getValue(); if(states != null) allStates.addAll(states); }``` 这样就解决了问题。感谢@GuilhermeBrabo 的帮助
猜你喜欢
  • 1970-01-01
  • 2018-01-09
  • 2013-02-12
  • 2013-07-15
  • 1970-01-01
  • 1970-01-01
  • 2020-11-17
  • 2011-07-05
  • 1970-01-01
相关资源
最近更新 更多