问题导入:如果一个线程调用了一个对象的同步方法,那么他还能不能在调用这个对象的另外一个同步方法呢?
这里就是synchronized锁重入问题。
一.synchronized锁重入
来看下面的代码:
.这个是三个同步方法的类
public class Synfun_UseSynfun{ //同步方法1 public synchronized void fun1(){ System.out.println("我是一号同步方法"); this.fun2();//调用二号同步方法 } //同步方法2 public synchronized void fun2(){ System.out.println("我是二号同步方法"); this.fun3();//调用三号同步方法 } //同步方法3 public synchronized void fun3(){ System.out.println("我是三号同步方法"); } }
线程类,在run方法中调用一号同步方法:
public class SynThreadText extends Thread { private Synfun_UseSynfun synfun_useSynfun;//组合上面类 public SynThreadText(Synfun_UseSynfun synfun_useSynfun){ this.synfun_useSynfun=synfun_useSynfun;//初始化上面的类 } @Override public void run(){ synfun_useSynfun.fun1();//调用对象类的同步方法 } public static void main(String[] args) { Synfun_UseSynfun synfun_useSynfun =new Synfun_UseSynfun(); SynThreadText synThreadText=new SynThreadText(synfun_useSynfun); synThreadText.start();//开启线程 } }
结果如下:
总结:可以看出一个线程调用了一个对象的同步方法,那么他也可以调用这个对象的另外一个同步方法。
二.synchronized锁重入支持父类继承
那么既然synchronized支持对象的方法重入,那么他是否也支持子类继承父类的同步方法重入呢?
不妨这样设计代码,在父类中有一个同步方法,子类继承这个方法,并且在创建一个子类的同步方法,在这个同步方法中去调用父类的同步方法。
代码如下:
public class SubClass extends SuperClass implements Runnable { @Override public void run(){ this.subSynFun(); } //子类的同步方法 public synchronized void subSynFun(){ System.out.println("子类的同步方法"); this.superSynFun(); } public static void main(String[] args) { SubClass sub=new SubClass(); Thread t =new Thread(sub); t.start(); } } //父类 class SuperClass{ //父类的同步方法 public synchronized void superSynFun(){ System.out.println("父类的同步方法"); } }
结果如下:
说明synchronized的方法是可以重入自己的父类同步化方法。
但是在这里要注意一点的:当你去重写父类中的同步方法,如果想要达到同步的效果重写方法也必须是同步化的,反面教材代码如下:
public class SubClass2 extends SuperClass2 implements Runnable{ @Override public void run(){ } //重写后的方法不为同步的 @Override public void superSynfun(){ System.out.println("子类中重写了父类中的同步方法,改为非同步"); } } //父类 class SuperClass2{ //父类的同步方法 public synchronized void superSynfun(){ System.out.println("父类的同步方法"); } }
重写的方法也必须是同步化的才能实现同步。