我在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得到崩溃报告。
最佳答案
必须修改基础集;即node.getOpenPorts()
返回的集合。
您可以复制它,而不用“不可修改的”包装器包装该集合。
final Set<Port> portSet = new HashSet<>(node.getOpenPorts());
但是,正如评论者(@Slaw)指出的那样,只需将迭代移入构造函数内部,您仍将获得CCME。
唯一真正的解决方案是:
更改节点类的实现,以将并发集类用于端口列表,如果在迭代过程中对集合进行了更改,则不会抛出CCME。
更改节点类的实现以返回端口列表的副本。使用一些内部锁定来处理“边复制边更新”竞争条件。
尝试一下/遍历代码,如果获得CCME,则重复该操作
我从来没有亲眼目睹过,但是我从Google得到崩溃报告。
是。仅当更改开放端口列表时执行此代码时,才会出现此问题。