每次我运行程序时,这个线程抛出这个异常,我似乎无法找到它的原因 . 有人可以试着解释为什么会发生这种情况吗?
package GPS.gpsproject;
import GPS.Model.Event;
import GPS.Model.Vehicle;
import java.time.Duration;
import java.time.LocalDate;
import java.util.List;
public class Notify extends Thread {
private List<Veiculo> vehicles;
private Controler controler;
public Notify(List<Veiculo> vehicles, Controlador controler) {
this.controler= controler;
this.vehicles= vehicles;
}
@Override
public void run() {
while (true) {
for (Vehicle v : vehicles) {
for (Event e : v.getEvents()) {
if (Duration.between(e.getData().atStartOfDay(), LocalDate.now().atStartOfDay()).toDays() < e.getDiasAntes() && !e.isNotified()) {
e.setNotified(true);
controler.sendNotification("Notification", e.getDesc());
}
}
}
}
}
例外:
Exception in thread "Thread-4" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at GPS.gpsproject.Notifica.run(Notify.java:25)
sendNotification()方法只是通知用户该事件
3 回答
当thread2修改
ArrayList
(例如,添加新元素)时,thread1使用它进行迭代for (Vehicle v : vehicles)
thread1将抛出
ConcurrentModificationException
,这称为fail-fast .您可能想要使用CopyOnWriteArrayList:
我假设
Notifica
和Notify
指的是同一个类(其中一个必须是拼写错误) . 您正在将List<Veiculo>
传递给Notifica
类的构造函数 . 然后在run()
方法中迭代List
.假设您在嵌套for循环中调用的方法不会修改
vehicles
列表或Event
的任何内部集合,这意味着当您迭代它们时,某些其他线程必须在任何这些集合中进行结构更改 .由于
vehicles
在迭代时不应进行结构修改,因此可能的解决方案可能是在构造函数中创建一个副本:请注意,这仅在其他线程不在属于
Veiculo
实例的Event
的内部集合中进行结构更改时才起作用,因为这是一个浅表副本 .导致该问题的原因是,您可能只创建一个车辆ArrayList并将相同的ArrayList传递给多个线程创建 . 在这种情况下,多个线程将访问相同的ArrayList对象 . 要避免相同的情况,您可以在创建Notify类对象时创建新的ArrayList并将其传递给构造函数,或者您可以更改Notify类下面的代码广告 .