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