我正在尝试创建简单的JAVA程序。但自从去年以来,我遇到了这个问题,我无法解决。
public void receiveUpdate(ArrayList<Connection> connections) {
for(Connection senderConnection : connections) {
for(Connection receiverConnection : this.connections) {
if(senderConnection.getDestination() == receiverConnection.getDestination()) {
if(senderConnection.getDistance() + 1 < receiverConnection.getDistance()) {
senderConnection.setEnabled(false);
senderConnection.setDistance(senderConnection.getDistance() + 1);
this.connections.remove(receiverConnection);
this.connections.add(senderConnection);
}
}
}
senderConnection.setEnabled(false);
senderConnection.setDistance(senderConnection.getDistance() + 1);
this.connections.add(senderConnection);
}
}
在这种方法中我总是得到错误:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at router.Router.receiveUpdate(Router.java:56)
at router.Router.sendUpdate(Router.java:49)
at loader.Loader.notifyNetworkChanges(Loader.java:61)
at loader.Loader.main(Loader.java:102)
我注意到,如果我评论阻止,那么例外情况就不会出现:
senderConnection.setEnabled(false);
senderConnection.setDistance(senderConnection.getDistance() + 1);
this.connections.add(senderConnection);
谁能告诉我,问题出在哪里?
答案 0 :(得分:2)
ConcurrentModificationException当不允许进行此类修改时,检测到并发修改对象的方法可能抛出此异常。 问题出在这里
this.connections.remove(receiverConnection);
当不允许进行此类修改时,检测到对象的并发修改的方法可能抛出此异常。 例如,一个线程通常不允许修改Collection而另一个线程正在迭代它。通常,在这些情况下,迭代的结果是不确定的。如果检测到此行为,某些Iterator实现(包括JRE提供的所有通用集合实现的实现)可能会选择抛出此异常。执行此操作的迭代器称为失败快速迭代器,因为它们快速而干净地失败,而不是在未来的未确定时间冒着任意的,非确定性行为的风险。
请注意,此异常并不总是表示某个对象已被另一个线程同时修改。如果单个线程发出违反对象合同的一系列方法调用,则该对象可能会抛出此异常。例如,如果线程在使用失败快速迭代器迭代集合时直接修改集合,则迭代器将抛出此异常。
检查this
要解决您的问题,您需要使用Iterator
和remove()
这样的方法
Iterator<String> connectionsIterator = connections.iterator();
while (connectionsIterator.hasNext()) {
if (senderConnection.getDistance() + 1 < receiverConnection.getDistance()){
connectionsIterator.remove();
// add the connection to another list other than this.connections.add(senderConnection);
// then when you finish add them back the this.connections
// so you avoid modifying this.connections
}
}
答案 1 :(得分:1)
实际上,您正在迭代时修改集合。
this.connections.remove(receiverConnection);
this.connections.add(senderConnection);
Iterator<String> iter = connections.iterator();
while (iter.hasNext()) {
if (someCondition)
iter.remove();
}
使用Iterator删除方法而不是ArrayList
答案 2 :(得分:0)
您正在循环浏览this.connections
并在内部尝试从this.connections
移除此java.util.ConcurrentModificationException
。更改代码以使用迭代器。
答案 3 :(得分:0)
如果您正在修改(例如删除)您正在循环的相同列表,那么您一定会得到ConcurrentModificationException
您可以使用提及的@ ankur-singhal迭代器,也可以制作列表的深层副本并从该副本中删除。然后,您可以指定原始列表的引用以指向具有修改的新引用。
另一个&#34;贪心&#34;方法(但不使用迭代器)将保留所有项目在另一个新列表中删除,并在结束for循环后调用removeAll(listOfConnectionsToBeRemoved),例如:
在for循环之前
ArrayList<Connection> connectionsToBeRemoved = new ArrayList<Connection>();
在你的for循环中
connectionsToBeRemoved.add(receiverConnection)
结束你的for循环后
this.connections.removeAll(connectionsToBeRemoved)
*您可以对要添加的连接执行相同操作。将它们保存在新列表中,然后将它们全部添加到连接列表中。