我要
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());
答案 0 :(得分:0)
我看不到当前代码在哪里修改了该集合。因此,对象成员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()...
// 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<>());
或使用普通同步(所有修改都需要锁以及您发布的代码)。