java - ArrayList.addAll() 并发修改异常

标签 java

在 Java 8 (OpenJDK) 中实现一种 Kademlia 存储桶时,我遇到了一些非常奇怪的问题。

我需要从所谓的 Buckets 中获取至少特定数量的项目。 但这不是问题。

不知何故,我在 ArrayList 上执行 closest.addAll() 时有时会遇到 ConcurrentModificationException,尽管它只是在单个线程中使用并且我没有迭代或做类似的事情。

你知道如何帮助我吗? 这是我的代码(我知道它一团糟!):

List<Neighbour> getClosest(Node n, int num) {
    ArrayList<Neighbour> closest = new ArrayList<>();
    int missing;
    int walkDown = n.getBucket(me);
    int walkUp = walkDown + 1;
    boolean pleaseBreak = true;
    while (true) {
        missing = num - closest.size();
        if (missing <= 0) {
            return closest;
        }

        if (walkUp >= 0 && walkUp < 160) {
            List<Neighbour> l = buckets[walkUp].getClosest(missing);
            closest.addAll(l);
            if (closest.size() >= missing) {
                return closest;
            }
            walkUp++;
            pleaseBreak = false;
        }

        if (walkDown >= 0 && walkDown < 160) {
            List<Neighbour> l = buckets[walkDown].getClosest(missing);
            closest.addAll(l);
            if (closest.size() >= missing) {
                return closest;
            }
            walkDown--;
            pleaseBreak = false;
        }

        if (pleaseBreak) {
            return closest;
        }
        pleaseBreak = true;
    }
}

最佳答案

ConcurrentModificationException实际上意味着您通过在迭代列表时以某种方式修改列表来打破迭代规则。

Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

也就是说,很明显是什么导致了这个问题。因为 closest 是一个新的 List 被方法填充,它必须是 l 被修改。

有两种选择:

  1. 另一个线程正在执行它。
  2. 您已经在列表 l 中打开了一个迭代器。

假设它不是 1(或者您可能已经提到过)我会选择:

您的 getClosest 方法正在返回正在迭代和/或修改的列表的子列表,并且 addAll 也在尝试迭代它。

要解决此问题,请使 getClosest 返回子列表的副本

关于java - ArrayList.addAll() 并发修改异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28088085/

相关文章:

Java BufferedInputStream.read() IndexOutOfBounds

java - 使用 Apache Camel/Smallrye/reactive 流 - 如何跨 JVM 将 "publisher"连接到 "subscriber"?

java - Android 应用程序在启动时崩溃

java - 在线程之间共享 bin 数组

java - 使用 Java 的 File.delete() 方法

Java:作为控制流的异常?

java - 生成带有 svg 内容的图标

java - ehcache RMI 配置到 spring

java - 避免在 Java 中重叠正则表达式匹配

java - 带反斜杠转义的字符串的正则表达式