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