可重入锁定

Cap*_*ngs 11 java concurrency locking reentrancy

请稍微帮忙,考虑下面的代码.

public class Widget {
    public synchronized void doSomething() {
        ...
    }
}

public class LoggingWidget extends Widget {
    public synchronized void doSomething() {
        System.out.println(toString() + ": calling doSomething");
        super.doSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

我读到当调用LoggingWidget中的doSomething()时,JVM将首先尝试获取LoggingWidget上的锁定,然后尝试获取Widget上的锁定.

我很想知道原因.是因为JVM知道doSomething()调用了super.doSomething(),或者因为调用子类方法也总是会获得对超类的锁定.

干杯

oxb*_*kes 9

你错了 - 锁是在实例级获得的.您的示例中只有一个锁,因为只有当您说:

Widget w = new LoggingWidget
Run Code Online (Sandbox Code Playgroud)

您可以将锁(也称为监视器,互斥锁信号量)视为单独"附加"到每个对象实例中JVM.

如果你synchronizedLoggingWidget子类上有另一个方法,你会发现这是真的.不可能同时调用此(新)方法和doSomething方法[在同一对象上使用不同的线程].

这也适用synchronized于超类上的另一个方法(即,它不会被覆盖的方法以任何方式受到影响).


baj*_*ife 5

public synchronized void doSomething() {
    System.out.println(toString() + ": calling doSomething");
    super.doSomething();
}
Run Code Online (Sandbox Code Playgroud)

是相同的:

public void doSomething() {
    synchronized (this) {
        System.out.println(toString() + ": calling doSomething");
        super.doSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

你锁定了实例,而不是类.因此,当调用super.doSomething()时,您已经锁定了该实例.