java - 我找不到我的 java.util.ConcurrentModificationException 的原因

标签 java concurrentmodification

我的 Main 方法中有进入 for 循环的代码。

for (List<Point2D> points : output) {
    currentPath = pathDistance(points);
    if (shortest == 0){
        shortest = currentPath;
    } else if (currentPath < shortest) {
        best = points;
        shortest = currentPath;
    }
}

其中 pathDistance 定义为

public static Double pathDistance(List<Point2D> path){
    double distance = 0;
    int count = path.size()-1;

    for (int i = 0; i < count; i++) {
        distance = distance + path.get(i).distance(path.get(i+1));
    }

    distance = distance + path.get(0).distance(path.get(count));
    return distance;
}

但是我一直报错

Exception in thread "main" java.util.ConcurrentModificationException
   at java.util.SubList.checkForComodification(Unknown Source)
   at java.util.SubList.size(Unknown Source)
   at java.util.Collections$SynchronizedCollection.size(Unknown Source)
   at TSMain.pathDistance(TSMain.java:76)
   at TSMain.main(TSMain.java:203)

我知道这应该意味着我正在改变一个对象,而迭代依赖于它,但我无法在我的生活中弄清楚可能发生的地方。任何帮助,将不胜感激。

最佳答案

您的堆栈跟踪显示您的代码 subList 中的某处已传递给 Collections.synchronizedCollection (直接或间接)。像这样

Set<List<Point2D>> output = Collections.singleton(
    Collections.synchronizedCollection(data.subList(start, end)));

但是它不会复制data 列表。而 points subList 仍然指向 data 列表中的一个范围。 原始列表在 path.size() 调用发生时被修改。

在将它传递给 pathDistance

之前,您可以通过显式列表复制轻松解决您的问题
for(List<Point2D> points : output){
    List<Point2D> pointsCopy = new ArrayList<>(points)
    currentPath = pathDistance(pointsCopy);
    // rest of code using pointsCopy
}

我还应该注意到,您的代码中似乎存在同步问题。在同步集合中包装子列表是一个坏主意,因为原始列表可能会以不安全的方式修改而没有适当的同步。

您可以通过查看 AbstractList#modCount 了解有关列表修改检查的更多信息来源。

关于java - 我找不到我的 java.util.ConcurrentModificationException 的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39498138/

相关文章:

java - 在 java 中重新打开文件的正确方法是什么?

java - 三叉树的前序遍历

java - 从 Java 对象生成 Spring bean 定义

java - java并发修改异常,我想我这里不能使用迭代器吗?

java - 单核处理器还能抛出ConcurrentModificationException吗?

java - 防止并发修改异常的最佳方法

java - ConcurrentModificationException 定时器任务

java - 如何为线程池中的各个线程设置时间限制?

java - 为什么会抛出 ConcurrentModificationException 以及如何调试它

java - 单击时让播放器移动到我的鼠标?