为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

吃鸡游戏 2022-01-12 14:41:30
我在 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 的崩溃报告。
查看完整描述

1 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

一定有什么东西在修改底层集合;即返回的集合node.getOpenPorts()

您可以复制它,而不是用“不可修改的”包装器包装集合。

    final Set<Port> portSet = new HashSet<>(node.getOpenPorts());

但正如评论者(@Slaw)指出的那样,这只是将迭代移动到构造函数中,您仍然会获得 CCME。

唯一真正的解决方案是:

  • 更改节点类的实现以对端口列表使用并发集类,如果在迭代时集合发生突变,则不会抛出 CCME。

  • 更改节点类的实现以返回端口列表的副本。使用一些内部锁定处理复制时更新的竞争条件。

  • 如果您获得 CCME,请在代码周围放置一个 try/catch 并重复该操作


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

是的。只有在打开端口列表更改时执行此代码时才会出现此问题。


查看完整回答
反对 回复 2022-01-12
  • 1 回答
  • 0 关注
  • 111 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信