2

効果的なJavaから(第10章同時実行性)

同期領域によって保護されている不変条件が一時的に無効であるときに、同期領域内からエイリアンメソッドを呼び出すことになったとします。Javaプログラミング言語のロックは再入可能であるため、このような呼び出しはデッドロックしません

次のコードを見てください。

// Broken - invokes alien method from synchronized block!
public class ObservableSet<E> extends ForwardingSet<E> {
  public ObservableSet(Set<E> set) {
    super(set);
  }

  private final List<SetObserver<E>> observers = new ArrayList<SetObserver<E>>();

  private void notifyElementAdded(E element) {
    synchronized (observers) {
      for (SetObserver<E> observer : observers)
        observer.alienMethod(this, element);
    }
  }
}

したがってSetObserversObservableSet2つの独立して記述されたクラスであり、それらは異なるパッケージに存在するため、クラスにとっては異質alienMethod()であると考えてください。ここで、呼び出されたときにオブザーバーが一貫した状態にないことを言います。では、リエントラントロックの問題はどこにあるのでしょうか。再入可能性が問題になるのは、エイリアンメソッドも同じロック、つまり「オブザーバー」で同期する場合だけですが、ここではそうではないようです。SetObserverObservableSetalienMethod

4

1 に答える 1

6

そして、原因によってイベントが発生し、同じメソッドalienMethodを再入力した場合はどうなりますか?notifyElementAddedこれは現実世界の危険です、私は一度それによって噛まれました。

この特定のケースでは、リストの安全なコピーを作成し、それを安心して実行する必要があります。

于 2012-07-20T12:42:26.797 に答える