我应该同步notifyObservers调用吗?

时间:2016-09-06 18:51:19

标签: java multithreading observable observer-pattern synchronized

我发现了Observable的这个实现:

public class ObservableObject extends Observable {
    private static ObservableObject instance = new ObservableObject();

    public static ObservableObject getInstance() {
        return instance;
    }

    private ObservableObject() {
    }

    public void updateValue(Object data) {
        synchronized (this) {
            // The call to setChanged marks this Observable object as having been changed; the hasChanged method will now return true.
            setChanged();
            notifyObservers(data);
        }
    }
}

我试图理解的是default implementation同步块的使用和我在上面找到的代码中使用synchronized块之间的区别是什么?是否需要?有更好的(正确的)方式吗?

1 个答案:

答案 0 :(得分:3)

你不应该在持有锁的情况下调用notifyObservers。由于链接代码注释中引用的原因,发布的代码有缺陷:

  

我们不希望Observer在拥有自己的Monitor时进行任意代码回调。我们从Vector中提取每个Observable并存储Observer状态的代码需要同步,但是通知观察者不会(不应该)。这里任何潜在竞争条件的最糟糕结果是:

     

1)新添加的观察者将错过正在进行的通知

     

2)最近未注册的观察者在不关心的时候会被错误地通知

方法notifyObservers包括更新观察者的调用,java.util.Observable代码小心地保持不同步。如果observable在更新观察者时持有自己的锁,那么observable无法控制观察者的操作,就不知道锁可以持有多长时间,从而影响了observable的响应能力。