【发布时间】:2015-01-12 10:53:25
【问题描述】:
下面是一些“Java 实践中的并发”的可重入锁定示例代码:
class Widget {
public synchronized void doSomething() {
System.out.println(toString() + ": calling superclass doSomething");
}
}
class LoggingWidget extends Widget {
public synchronized void doSomething() {
System.out.println(toString() + ": calling subclass doSomething");
super.doSomething();
}
}
这本书在上面的代码中解释了...... “因为 Widget 和 LoggingWidget 中的 doSomething 方法都是同步的,所以在继续之前,每个方法都会尝试获取 Widget 上的锁。”
我运行上面的代码来观察内在锁。上面的引用似乎暗示一个线程在 Widget 对象上获得了一个内在锁,但我观察到该线程在 LoggingWidget 上获得了一个锁。我不确定如何验证获取计数,因此无法观察到这一点。
这本书是交替使用名称 LoggingWidget/Widget 还是我应该专门观察 Widget 对象上的锁定?
编辑:全文摘录
可重入性有助于封装锁定行为,因此 简化了面向对象并发代码的开发。没有 可重入锁,清单 2.7 中看起来非常自然的代码,在 哪个子类覆盖同步方法,然后调用 超类方法,会死锁。因为 doSomething 方法在 Widget 和 LoggingWidget 都是同步的,各自尝试获取 在继续之前锁定小部件。但是如果内在锁是 不可重入,对 super.doSomething 的调用将永远无法 获取锁,因为它会被认为已经持有,并且 线程将永久停止等待它永远无法获得的锁 获得。在这种情况下,重入使我们免于陷入僵局。
【问题讨论】:
-
一个线程死锁 - 对我来说看起来很奇怪
标签: java concurrency locking reentrancy