深入理解Java中的synchronized锁重入

问题导入:如果一个线程调用了一个对象的同步方法,那么他还能不能在调用这个对象的另外一个同步方法呢?

这里就是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("父类的同步方法");
    }
}

 

 重写的方法也必须是同步化的才能实现同步。

 

posted on 2018-10-17 11:15  真正的小明被占用了  阅读(2784)  评论(0编辑  收藏  举报

导航