关于重入的代码举例:
public class Widget{
public synchronized void doSomething(){
...
}
}
public class LoggingWidget extends Widget{
public synchronized void doSometing(){
System.out.println(toString() + ": calling doSomething");
super.doSomething();
}
}
这里如果调用了子类的doSometing方法,synchronized所使用的锁对象一直是子类对象,super.doSomething()锁对象也是子类对象。
为什么不是父类对象呢?我们来看下再这个例子中我们一般是怎么创建对象和调用方法的:
LoggingWidget lw = new LoggingWidget (); // 这里我们只创建了一个对象,是子类对象
lw.doSomething();
这里有几点原则:
1、synchronized函数,实际是synchronized(this)代码块包裹整个函数的简写,所用的锁就是当前this对象,要验证是否是同一个锁对象,实际我们可以再父类和子类的doSomething()方法中打印出this即可。
2、关于继承和super调用,并不会创建一个父类对象给子类对象去引用。
PS:静态方法同步所用的是class锁,这又是另外一回事
网友评论