3

私が観察のこの実装を見つけた:notifyObservers呼び出しを同期する必要がありますか?

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使用して、私は上記の見つけコードで同期ブロックの使用の違いは何かあることを理解しようとしています、両方の必要があるのですか?より良い(正しい)方法がありますか?

+0

デフォルトの実装ではObservableインスタンスを使用してロックを取得し、ObservableObjectクラスはObservableのサブクラスであるため、同じオブジェクトを2回ロックする以外に違いはないと思います。両方のインスタンスで現在のObservableObjectインスタンスがロックされます – ManZzup

+0

@ManZzupデフォルトの実装では、指定された実装がそれ自体でロックするところでデータをロックします – dosdebug

答えて

3

ロックを保持した状態でnotifyObserversを呼び出すべきではありません。投稿のコードでは、リンクされたコードのコメントに引用された理由のために欠陥がある:私たちは、独自のモニターを保持しながら、オブザーバーは、任意のコードへのコールバックをやってほしくない

。 Observableをベクトルから抽出し、Observerの状態を保存するコードは同期が必要ですが、オブザーバに通知することはできません。ここでは、潜在的な競合状態の最悪の結果は、ということです:新しく追加されたオブザーバーが進行

2に通知を欠場する

1))、それは気にしないとき、最近未登録のオブザーバーが誤って通知されます

メソッドnotifyObserversには、java.util.Observableコードが非同期のままにしておいたオブザーバを更新するための呼び出しが含まれています。オブザーバがオブザーバを更新している間にオブザーバブルがロックを保持している場合、オブザーバはオブザーバの操作を制御できません。

+0

ありがとうございました。 –

関連する問題