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

问题描述 投票:0回答:1

我在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("  ");
    }
}

我从来没有见过这个,但是我收到谷歌的崩溃报告。

java android concurrency
1个回答
3
投票

必须要修改基础集;即node.getOpenPorts()返回的集合。

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

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

但是作为一个评论者(@Slaw)指出,这只是在构造函数中移动迭代,你仍然会得到CCME。

唯一真正的解决方案是:

  • 更改节点类的实现以使用端口列表的并发集类,如果在迭代时集合发生变化,则不会抛出CCME。
  • 更改节点类的实现以返回端口列表的副本。使用一些内部锁定处理复制时更新竞争条件。
  • 对代码进行try / catch并在获得CCME时重复操作

我从来没有见过这个,但是我收到谷歌的崩溃报告。

是。如果在打开端口列表更改时执行此代码,则只会出现此问题。

© www.soinside.com 2019 - 2024. All rights reserved.