有很多并发mod异常问题,但我找不到帮助我解决问题的答案。如果您找到答案,请提供链接而不是仅仅投票。
所以我在尝试搜索arraylist并删除元素时最初遇到并发mod错误。有一段时间,我通过创建第二个arraylist,将发现的元素添加到它,然后在for循环外使用removeAll()来解决它。这似乎工作,但当我使用for循环从多个文件导入数据时,我开始再次获得并发修改异常,但由于某种原因间歇性地。任何帮助将不胜感激。
这是具有问题的具体方法(以及它调用的其他方法......):
public static void removeData(ServiceRequest r) {
readData();
ArrayList<ServiceRequest> targets = new ArrayList<ServiceRequest>();
for (ServiceRequest s : serviceQueue) {
//ConcurrentModification Exception triggered on previous line
if (
s.getClient().getSms() == r.getClient().getSms() &&
s.getTech().getName().equals(r.getTech().getName()) &&
s.getDate().equals(r.getDate())) {
JOptionPane.showMessageDialog(null, s.getClient().getSms() + "'s Service Request with " + s.getTech().getName() + " on " + s.getDate().toString() + " has been removed!");
targets.add(s);
System.out.print("targetted"); }
}
if (targets.isEmpty()) { System.out.print("*"); }
else {
System.out.print("removed");
serviceQueue.removeAll(targets);
writeData(); }
}
public static void addData(ServiceRequest r) {
readData();
removeData(r);
if (r.getClient().getStatus().equals("MEMBER") || r.getClient().getStatus().equals("ALISTER")) {
serviceQueue.add(r); }
else if (r.getClient().getStatus().equals("BANNED") || r.getClient().getStatus().equals("UNKNOWN")) {
JOptionPane.showMessageDialog(null, "New Request failed: " + r.getClient().getSms() + " is " + r.getClient().getStatus() + "!", "ERROR: " + r.getClient().getSms(), JOptionPane.WARNING_MESSAGE);
}
else {
int response = JOptionPane.showConfirmDialog(null, r.getClient().getSms() + " is " + r.getClient().getStatus() + "...", "Manually Overide?", JOptionPane.OK_CANCEL_OPTION);
if (response == JOptionPane.OK_OPTION) {
serviceQueue.add(r); }
}
writeData(); }
public static void readData() {
try {
Boolean complete = false;
FileReader reader = new FileReader(f);
ObjectInputStream in = xstream.createObjectInputStream(reader);
serviceQueue.clear();
while(complete != true) {
ServiceRequest test = (ServiceRequest)in.readObject();
if(test != null && test.getDate().isAfter(LocalDate.now().minusDays(180))) {
serviceQueue.add(test); }
else { complete = true; }
}
in.close(); }
catch (IOException | ClassNotFoundException e) { e.printStackTrace(); }
}
public static void writeData() {
if(serviceQueue.isEmpty()) { serviceQueue.add(new ServiceRequest()); }
try {
FileWriter writer = new FileWriter(f);
ObjectOutputStream out = xstream.createObjectOutputStream(writer);
for(ServiceRequest r : serviceQueue) { out.writeObject(r); }
out.writeObject(null);
out.close(); }
catch (IOException e) { e.printStackTrace(); }
}
修改
这些更改会导致并发mod每次都触发而不是间歇性触发,我猜这意味着删除代码更好但现在错误触发it.remove();
public static void removeData(ServiceRequest r) {
readData();
for(Iterator<ServiceRequest> it = serviceQueue.iterator(); it.hasNext();) {
ServiceRequest s = it.next();
if (
s.getClient().getSms() == r.getClient().getSms() &&
s.getTech().getName().equals(r.getTech().getName()) &&
s.getDate().equals(r.getDate())) {
JOptionPane.showMessageDialog(null, s.getClient().getSms() + "'s Service Request with " + s.getTech().getName() + " on " + s.getDate().toString() + " has been removed!");
it.remove(); //Triggers here (line 195)
System.out.print("targetted"); }
}
writeData(); }
线程“AWT-EventQueue-0”中的异常java.util.ConcurrentModificatio n异常 at java.util.ArrayList $ Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList $ Itr.next(ArrayList.java:851) at data.ServiceRequest.removeData(ServiceRequest.java:195) at data.ServiceRequest.addData(ServiceRequest.java:209)&lt; ...&gt;
修改 经过一些搜索,我将for循环切换为:
Iterator<ServiceRequest> it = serviceQueue.iterator();
while(it.hasNext()) {
它又回到间歇性触发。我的意思是我第一次尝试导入数据(从addData方法触发removeData方法)它会触发并发mod异常,但是下一次尝试它会推迟失败并转移到另一个文件。我知道有很多这些并发的mod问题,但我找不到任何对我的情况有帮助的东西,所以非常欢迎链接到其他答案......
答案 0 :(得分:1)
这不是如何做到这一点,在通过使用迭代器的List时删除元素。像那样:
List<ServiceRequest> targets = new ArrayList<ServiceRequest>();
for(Iterator<ServiceRequest> it = targets.iterator(); it.hasNext();) {
ServiceRequest currentServReq = it.next();
if(someCondition) {
it.remove();
}
}
如果你只有一个帖子,你就不会以这种方式得到ConcurrentModificationException。
如果代码中涉及多个线程,您可能仍会收到ConcurrentModificationException。解决此问题的一种方法是在集合(serviceQueue)上使用Collections.synchronizedCollection(...),因此您将获得不会产生ConcurrentModificationException的同步集合。但是,你的代码可能会变得很慢。