2

来自Effective 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);
    }
  }
}

因此,考虑SetObserversObservableSet是两个独立编写的类,它们位于不同的包中,因此alienMethod()与类SetObserver无关ObservableSetalienMethod现在说观察者在被调用时处于不一致的状态。那么可重入锁的问题在哪里呢?如果外星人方法也在同一个锁(即“观察者”)上同步,那么重入性只会受到质疑,但这里似乎不是这种情况,或者我在这里遗漏了什么?

4

1 回答 1

6

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

在这种特殊情况下,您必须制作一份安全的清单副本,然后安静地浏览它。

于 2012-07-20T12:42:26.797 回答