在 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
被修改。
有两种选择:
- 另一个线程正在执行它。
- 您已经在列表
l
中打开了一个迭代器。
假设它不是 1(或者您可能已经提到过)我会选择:
您的 getClosest
方法正在返回正在迭代和/或修改的列表的子列表,并且 addAll
也在尝试迭代它。
要解决此问题,请使 getClosest
返回子列表的副本。
关于java - ArrayList.addAll() 并发修改异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28088085/