深入理解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("父類的同步方法");
    }
}

 

 重寫的方法也必須是同步化的才能實現同步。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM