我正在做一些使用观察者设计模式的项目。
学科类是:
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
。我错过了什么吗?
最佳答案
两件事同时发生:您正在迭代 observers
并向 observers
添加一个元素。这会导致您的 ConcurrentModificationException
一般来说,你至少可以做三件事:
observers
的访问与 synchronized
块: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);
}
}
synchronized
,但是它们将在 Subject
的实例上而不是在集合实例上同步。 但是,在您的情况下,问题与您的
update()
的作用有关。你确定你的
HexaObserver
的 update
应该创建一个新的 HexaObserver
吗?因为您正在将同一类的新实例添加到已经包含该实例的集合中。关于使用 ExecutorService 时出现 java.util.ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30075035/