Java 并发修改执行
我有一个普通的数据库调用,它从我的数据库收集信息。我使用这些信息创建对象(Java 并发修改执行,java,loops,concurrentmodification,Java,Loops,Concurrentmodification,我有一个普通的数据库调用,它从我的数据库收集信息。我使用这些信息创建对象(CallQueue),然后将这些对象添加到列表中,然后返回列表 突然,我发现我最初的代码并没有按预期的那样工作,因为我创建了dublicates,所以现在我试图取消任何dublicates正在被创建!但是有一个问题 我无法在列表中循环并检查对象是否已创建 这是我的密码: while (query.next()) { if (!queues.isEmpty()) { /*This gives the
CallQueue
),然后将这些对象添加到列表中,然后返回列表
突然,我发现我最初的代码并没有按预期的那样工作,因为我创建了dublicates,所以现在我试图取消任何dublicates正在被创建!但是有一个问题
我无法在列表中循环并检查对象是否已创建
这是我的密码:
while (query.next()) {
if (!queues.isEmpty()) {
/*This gives the Execption->*/
for (CallQueue callQueue : queues) {
if (callQueue.getType().equals(query.getString("KØ"))) {
double decimalTime = query.getDouble("TID");
int hourOfDay = (int)Math.round(24 * decimalTime);
int callAmount = query.getInteger("ANTAL_KALD");
if (hourOfDay > 19) {
hourOfDay = 19;
}
callQueue.addCallsByTime(hourOfDay, callAmount);
} else {
String queueName = query.getString("Kø");
if (!queueName.equalsIgnoreCase("PrivatOverflow")) {
CallQueue cq = new CallQueue(query.getString("KØ"));
double decimalTime = query.getDouble("TID");
int hourOfDay = (int)Math.round(24 * decimalTime);
int callAmount = query.getInteger("ANTAL_KALD");
if (hourOfDay > 19) {
hourOfDay = 19;
}
cq.addCallsByTime(hourOfDay, callAmount);
queues.add(cq);
}
}
}
} else {
String queueName = query.getString("Kø");
if (!queueName.equalsIgnoreCase("PrivatOverflow")) {
CallQueue cq = new CallQueue(query.getString("KØ"));
double decimalTime = query.getDouble("TID");
int hourOfDay = (int)Math.round(24 * decimalTime);
int callAmount = query.getInteger("ANTAL_KALD");
if (hourOfDay > 19) {
hourOfDay = 19;
}
cq.addCallsByTime(hourOfDay, callAmount);
queues.add(cq);
}
}
}
for (CallQueue callQueue : queues) {
System.out.println(callQueue.getType());
}
query.Close();
return queues;
我从中得到的执行选项是:
Caused by: java.util.ConcurrentModificationException
我试着去查一下那封信
有人能帮我解决这个问题吗?您正在迭代中进行添加。根据规范,不允许修改正在迭代的集合 经典的解决方案是首先创建集合的副本,然后对其进行迭代。另一种解决方案是不使用迭代器(简短的foreach表示法隐式使用它),而是使用索引手动迭代
for (int i=0; i<queues.size(); i++) {
CallQueue callQueue = queues.get(i);
... code goes here
}
for(int i=0;i您正在迭代中进行添加。根据规范,您不允许修改正在迭代的集合
经典的解决方案是首先创建集合的副本并对其进行迭代。另一种解决方案是不使用迭代器(简短的foreach表示法隐式使用迭代器),而是使用索引手动迭代
for (int i=0; i<queues.size(); i++) {
CallQueue callQueue = queues.get(i);
... code goes here
}
for(int i=0;i使用set而不是List来避免此问题。您可以在要修改的同一列表上进行迭代
使用set而不是List来避免此问题。您可以在要修改的同一列表上进行迭代
请发布完整的堆栈跟踪。我的建议是:如果要在迭代时向其添加项,请按索引循环,而不是使用for-each构造。也许可以使用同步块来进行此循环。哪一行引发异常?请发布完整的堆栈跟踪。我的建议是:按索引循环,而不是使用for-each构造,如果您想在迭代时向其中添加项。也许您可以使用同步块来进行此循环。哪一行引发异常?@Marc您也可以使用CopyOnWriteArrayList,它包含了此写拷贝功能。@Joeri首先感谢您的回复。第二,您对我的代码有缺陷的评论,可以吗elaburate abit?我怎么才能不制作双副本呢?@MarcRasmussen基本上,检查是否找到元素需要在迭代之外。最好的方法是将find逻辑重构为自己的方法。这样,你也可以摆脱目前用于检查空元素的代码重复如果findQueue返回null,则无论列表是空的还是空的,都需要创建一个新的列表并添加它not@Marc您也可以使用CopyOnWriteArrayList,它包含了这种写拷贝功能。@Joeri首先感谢您的回复,第二,您对我的代码有缺陷的评论,您能帮我翻译一下吗?我该如何翻译lse是否不制作dublicates?@MarcRasmussen基本上,检查是否找到元素需要在迭代之外。最好的方法是将find逻辑重构为其自己的方法。这样,您还可以摆脱目前用于检查空列表的重复代码。如果findQueue返回null,您需要创建一个新列表并添加它,而不管列表是否为空