ConcurrentModificationException

ConcurrentModificationException

我正在做一些使用观察者设计模式的项目。
学科类是:

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() 的作用有关。
    你确定你的 HexaObserverupdate 应该创建一个新的 HexaObserver 吗?因为您正在将同一类的新实例添加到已经包含该实例的集合中。

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

    10-11 21:18