Я работаю над некоторым проектом, в котором я использую шаблон проектирования Observer. Тема класс:java.util.ConcurrentModificationException при использовании ExecutorService
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
выбрасывается, когда мы пытаемся изменить какой-либо объект одновременно, если это не допускается.
Я что-то упустил?
Похоже, что это происходит потому, что ваш HexaObserver добавляет элемент в список массива в то время как петля уведомления происходит. Попробуйте изменить «ArrayList» на параллельную реализацию, например, «CopyOnWriteArrayList» – BretC
BretC кажется правильным. Я не понимаю, почему в update() добавлен новый HexaObserver (включая неявное прикрепление в Constructor). Вероятно, 'submit (this)' был предназначен? Или подайте новый неизменный и потокобезопасный объект без неявного прикрепления. –
@Bret C: yaa [CopyOnWriterArrayList] будет работать, но это так дорого. Кстати, метод, предложенный Маркусом Куллом, тоже хорош. Я действительно намеревался это только. –