为什么我在这个 unmodifiableSet 上得到 ConcurrentModification

我在 for 循环开始的行上收到了 java.util.ConcurrentModificationException(请参阅代码中的注释)。


为什么我在这个 unmodifiableSet 上得到 ConcurrentModificationException?


final Set<Port> portSet = Collections.unmodifiableSet(node.getOpenPorts());

if (!portSet.isEmpty()) {

    StringBuilder tmpSb = new StringBuilder();

    for (Port pp : portSet) { // <------- exception happening here

        tmpSb.append(pp.getNum()).append("  ");

    }

}

我从未目睹过这种情况,但我收到了来自 Google 的崩溃报告。


吃鸡游戏
浏览 112回答 1
1回答

蛊毒传说

一定有什么东西在修改底层集合;即返回的集合node.getOpenPorts()。您可以复制它,而不是用“不可修改的”包装器包装集合。&nbsp;&nbsp;&nbsp;&nbsp;final&nbsp;Set<Port>&nbsp;portSet&nbsp;=&nbsp;new&nbsp;HashSet<>(node.getOpenPorts());但正如评论者(@Slaw)指出的那样,这只是将迭代移动到构造函数中,您仍然会获得 CCME。唯一真正的解决方案是:更改节点类的实现以对端口列表使用并发集类,如果在迭代时集合发生突变,则不会抛出 CCME。更改节点类的实现以返回端口列表的副本。使用一些内部锁定处理复制时更新的竞争条件。如果您获得 CCME,请在代码周围放置一个 try/catch 并重复该操作我从未目睹过这种情况,但我收到了来自 Google 的崩溃报告。是的。只有在打开端口列表更改时执行此代码时才会出现此问题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java