synchronize必须是重入锁,为什么呢? 就是因为父子类不会破坏继承基础思想:
父子类对象锁重入的意思是子类的同步方法调用了父类的同步方法同样不需要再去竞争锁,因为该线程已经拥有了该对象的锁,子类对象继承了父类的方法。
我们看下代码:
父类:
package com.ck.thread; public class Father { public synchronized void eat() { System.out.println("Father:吃饭"); xiwan(); System.out.println("Father:吃饭整个过程结束"); } public synchronized void xiwan() { System.out.println("Father:洗碗"); } }
子类中的洗手吃饭方法调用了父类的吃饭方法:
package com.ck.thread; public class Son extends Father{ public synchronized void xishouEat() { System.out.println("son : 洗手"); /** * 吃饭之前先洗手,洗完手再吃饭 */ eat(); } }
然后我们修改下吃饭的线程类:
package com.ck.thread; public class EatThread extends Thread{ private Son son; public EatThread(Son son) { super(); this.son = son; } public Son getSon() { return son; } public void setFather(Son son) { this.son = son; } @Override public void run() { son.xishouEat(); } }
执行主方法:
package com.ck.thread; public class MainThread { public static void main(String[] args) throws InterruptedException { Son son = new Son(); EatThread eatThread = new EatThread(son); eatThread.start(); } }
执行结果:
son : 洗手
Father:吃饭
Father:洗碗
Father:吃饭整个过程结束
总结:通过上面例子我们可以看到 xishouEat 方法调用父类eat方法的时候,可以直接调用,不需要等待,这就是synchronized 父子类锁重入 ,因为子类继承了父类实际上就是拥有了父类的public方法,所有父类的public 方法也属于子类对象。同一个对象同步方法调用就是我们上一篇讲的内容,同一个对象拥有了同一把锁,不需要竞争。