gpt4 book ai didi

使用 ExecutorService 时出现 java.util.ConcurrentModificationException

转载 作者:行者123 更新时间:2023-12-02 04:41:44 25 4
gpt4 key购买 nike

我正在开发一个使用观察者设计模式的项目。学科类别是:

public class Subject {
private List<Observer> observers = new ArrayList<Observer>();
private int state;
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
public void attach(Observer observer){
observers.add(observer);
}
public void notifyAllObservers(){
for (Observer observer : observers) {
observer.update();
}
}
public void deattach(Observer observer) {
observers.remove(observer);
}
}

观察者界面是:

public abstract class Observer implements Runnable{
protected Subject subject;
public abstract void update();
public abstract void process();
}

名为 HexObserver 的观察者之一是:

public class HexaObserver extends Observer {

private ExecutorService threadpool = Executors.newFixedThreadPool(10);

public HexaObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}

@Override
public void update() {
System.out.println("Hex String: "
+ Integer.toHexString(subject.getState()));
Future future = threadpool.submit(new HexaObserver(subject));

}

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("In run :D :D :D");

}

@Override
public void process() {
// TODO
}
}

测试这个的类是:

public class Demo {
public static void main(String[] args) {
Subject subject = new Subject();
HexaObserver hob = new HexaObserver(subject);
System.out.println("First state change: 15");
subject.setState(15);
}
}

当我尝试运行它时,出现一些错误:

First state change: 15
Hex String: f
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 Observer.Subject.notifyAllObservers(Subject.java:23)
at Observer.Subject.setState(Subject.java:15)
at Observer.Demo.main(Demo.java:12)
In run :D :D :D

我不明白为什么会收到此错误,因为当我们尝试在不允许的情况下同时修改某些对象时,会抛出 ConcurrentModificationException

我错过了什么吗?

最佳答案

有两件事同时发生:您正在迭代观察者并向观察者添加一个元素。这会导致您的 ConcurrentModificationException

一般来说,您至少可以做三件事:

  • 使用同步集合
  • 线程安全地复制集合并迭代副本
  • 使用synchronized block 手动同步对观察者的所有访问:

 

public void attach(Observer observer){
synchronized(observers){
observers.add(observer);
}
}
public void notifyAllObservers(){
synchronized(observers){
for (Observer observer : observers) {
observer.update();
}
}
}
public void deattach(Observer observer) {
synchronized(observers){
observers.remove(observer);
}
}
  • 您还可以将整个方法标记为同步,但随后它们将在 Subject 实例上同步,而不是在集合实例上同步。

但是,在您的情况下,问题与您的 update() 的作用有关。
您确定您的 HexaObserverupdate 应该创建一个新的 HexaObserver 吗?因为您要将同一类的新实例添加到已包含该实例的集合中。

关于使用 ExecutorService 时出现 java.util.ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30075035/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com