这是《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中非常自然的代码将导致死锁,其中子类覆盖同步方法,然后调用超类方法。由于Widget和LoggingWidget中的doSomething方法都是同步的,每个方法在继续之前都会尝试获取Widget上的锁。但是,如果内部锁不可重入,则对super.doSomething的调用永远无法获取锁,因为它被认为已经持有,并且线程将永久停滞等待永远无法获取的锁。可重入性在这种情况下避免了死锁。”