【问题标题】:ConcurrentModificationException when using stream使用流时出现 ConcurrentModificationException
【发布时间】:2019-07-05 13:12:49
【问题描述】:

我来了

ConcurrentModificationException(java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1558)) 

我怀疑我需要等到HashSet(nodeRefsWithTags) 完全填充后再处理它。或者有没有人有其他建议?

函数getTagRefs(sagerRef)被递归调用并填充nodeRefsWithTags

nodeRefsWithTags = new HashSet<>();
getTagRefs(sagerRef);

List<Tag> tags = nodeRefsWithTags.stream()
            .map(nodeRef -> ((List<NodeRef>)nodeService.getProperty(nodeRef, ContentModel.PROP_TAGS)))
            .filter(Objects::nonNull)
            .flatMap(Collection::stream)
            .map(taggingService::getTagName)
            .collect(Collectors.groupingBy(tagName -> tagName, Collectors.counting()))
            .entrySet().stream()
            .map(map -> new Tag(map.getKey(), map.getValue()))
            .collect(Collectors.toList());

【问题讨论】:

  • 您能否分享Minimal, Complete, and Verifiable example,以便我们重现您的问题?使用您共享的代码,无法判断错误可能出在哪里。
  • 引用的 Lambda 表达式似乎没问题。我想您省略的 stracktrace 指出了真正的问题......此外,调试代码将是您找出问题所在的最佳机会。

标签: java hashmap java-stream concurrentmodification


【解决方案1】:

我看不到当前代码修改集合的位置。所以对象成员nodeRefsWithTags 似乎可以被其他线程访问,并且必须有另一个并发线程对其进行修改。当您流式传输设置的项目时,不能保证不会进行任何修改。有一些选择:

创建一个副本:

// At this point, you have to make sure nodeRefsWithTags is not modified by other threads.
Set<...> copy = new HashSet<>(nodeRefsWithTags);
// From now on it's ok to modify the original set
List<Tag> tags = copy.stream()...

使用ConcurrentHashMap

// For this option you have to make sure that no elements get removed from the map, else you
// might get an endless loop (!) which is very hard to find and may occur occationally only.
nodeRefsWithTags = Collections.newSetFromMap(new ConcurrentHashMap<>());

或者使用普通同步(所有修改都需要锁以及您发布的代码)。

【讨论】:

  • 代码的目的是处理来自 Alfresco 环境的节点并提取它们的标签。它适用于小数据,但在某些情况下,有大量数据并且 CPU 被锁定在 100%。在这种情况下,由于数量很大,它似乎被卡住了,从未完成节点的进程。难道是递归不能处理大量的深度?但如果是这种情况,它不应该抛出堆栈溢出异常吗?
  • @Plv90 这是一个不同的问题。当 CPU 工作在 100% 并且 Java 进程变得非常慢时,请检查您的 RAM。 JVM 将所有资源都用于垃圾回收是非常典型的。
猜你喜欢
  • 2015-12-11
  • 1970-01-01
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
相关资源
最近更新 更多