从同步区域调用的可重入锁和外来方法(有效Java项)
来自有效Java(第10章并发性) 假设 当 由同步区域保护的不变量暂时无效。因为 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) {
// 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>和
alienMethod
时,观察者处于不一致的状态。那么重入锁的问题在哪里呢?只有当外星人方法也在同一个锁上同步(即“观察者”)时,重入性才会受到质疑,但这里似乎不是这样,或者我遗漏了什么 如果alienMethod
导致触发事件,并最终重新输入相同的notifyElementAdded
方法,会发生什么?这是一个现实世界的危险,我曾经被它咬过一次
在这种特殊情况下,您必须安全地复制您的列表,并和平地运行它。但这是您在这里做的一个特殊假设。根据您的假设,是的,副本可以解决问题,但报价中没有明确提到这一点。所以我们假设我们不知道外星人的方法会做什么,没有特别的假设指出外星人代码可能会重新输入相同的方法。它需要跳转的确切圈数是次要的。