在《Java並發編程實戰》中看到,如果synchronized不支持重入,如下代碼將會發生死鎖。言下之意就是:子類重寫父類synchronized方法,這兩個方法鎖住的對象一致。
public class Widget { public synchronized void doSomething() {...} } public class LoggingWidget extends Widget { @Override public synchronized void doSomething() { System.out.println(...); super.doSomething(); } }
但是,為什么一致?子類鎖住的是自己的對象,父類鎖住的應該是父類的對象啊?怎么兩個對象反而一樣了?遂做了如下實驗:
public class Widget { public synchronized void doSomething() { System.out.println("Widget中的this: " + this); } } public class LoggingWidget extends Widget { @Override public synchronized void doSomething() { super.doSomething(); System.out.println("LoggingWidget中的super: " + super.toString()); System.out.println("LoggingWidget中的this: " + this); } public static void main(String[] args) { LoggingWidget loggingWidget = new LoggingWidget(); loggingWidget.doSomething(); } }
運行結果如下:
很不可思議,super和this居然是同一個引用,而且父類的this也是。所以才會說鎖住的是同一個對象。也就是super本身仍然是子類的引用,只不過它可以調用到父類的方法或變量。