从同步区域调用的可重入锁和外来方法(有效Java项)

从同步区域调用的可重入锁和外来方法(有效Java项),java,java.util.concurrent,Java,Java.util.concurrent,来自有效Java(第10章并发性) 假设 当 由同步区域保护的不变量暂时无效。因为 Java编程语言中的锁是可重入的,这样的调用不会死锁 现在看下面的代码: // Broken - invokes alien method from synchronized block! public class ObservableSet<E> extends ForwardingSet<E> { public ObservableSet(Set<E> set) {

来自有效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);
    }
  }
}
//断开-从同步块调用外来方法!
公共类ObserviceSet扩展了ForwardingSet{
公共观测集(集合){
超级(套);
}
私有最终列表观察员=新的ArrayList();
私有void notifyElement已添加(E元素){
同步(观察员){
for(设置观察员:观察员)
观察者:alienMethod(本元素);
}
}
}

<> P> >代码> SET观察员< /COD>和StababLeSe> <代码>是两个独立的类,它们驻留在不同的包中,因此<代码> RealMead()/<代码> <代码> SETValue< /C> >与<代码>观察表< /代码>类不同。现在假设调用
alienMethod
时,观察者处于不一致的状态。那么重入锁的问题在哪里呢?只有当外星人方法也在同一个锁上同步(即“观察者”)时,重入性才会受到质疑,但这里似乎不是这样,或者我遗漏了什么

如果
alienMethod
导致触发事件,并最终重新输入相同的
notifyElementAdded
方法,会发生什么?这是一个现实世界的危险,我曾经被它咬过一次


在这种特殊情况下,您必须安全地复制您的列表,并和平地运行它。

但这是您在这里做的一个特殊假设。根据您的假设,是的,副本可以解决问题,但报价中没有明确提到这一点。所以我们假设我们不知道外星人的方法会做什么,没有特别的假设指出外星人代码可能会重新输入相同的方法。它需要跳转的确切圈数是次要的。