Java子類能不能繼承父類synchronized關鍵字?

今天在Github 看Java synchronized方面的知識總結時

看到一個有趣的說法“子類不能繼承父類的synchronized關鍵字”

我心裏的第一個想法是:爲什麼子類不能繼承父類的synchronized關鍵字呢

於是我決定用代碼實踐一下

 

首先,我先放上測試類主類的代碼,運行哪個則註釋其餘的代碼:

​
package com.way.test;

public class Main {

    public static void main(String[] args) {
//        注意初始化不能放在for循環中,
////        因爲synchronized是對象鎖, 鎖的是對象,
////        如果每次for循環中都新建了一個對象, 那麼這把鎖就毫無意義,怎樣運行都是異步的效果


        Father father = new Father();

        for (int i =0;i<5;i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    father.method();
                }
            }).start();
        }


//        Son son = new Son();
//
//        for (int i =0;i<5;i++) {
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    son.method();
//                }
//            }).start();
//        }


//        SonOverride sonOverride = new SonOverride();
//
//        for (int i = 0; i < 5; i++) {
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    sonOverride.method();
//                }
//            }).start();
//        }


    }
}

​
//        注意初始化不能放在for循環中,
//        因爲synchronized是對象鎖, 鎖的是對象,
//        如果每次for循環中都新建了一個對象, 那麼這把鎖就毫無意義,怎樣運行都是異步的效果

 

父類的代碼:

​
package com.way.test;

public class Father{

    public synchronized void method(){
        System.out.println("AA");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("BB");
    }

}

​

中間休眠一秒是爲了有足夠時間觀察方法是否“同步”,否則太快的話是可能看不出來。

運行結果:

可以看出AA——間隔一秒——BB是交替打印

然後,分別寫兩個子類,一個是直接繼承上面的父類

package com.way.test;

public class Son extends Father {
}

運行結果:

可以看出跟父類是一樣的,證明了是繼承了父類的synchronized關鍵字

而另外一個則是繼承並且重寫了父類的方法,注意這裏不要加上synchronized關鍵字

package com.way.test;

public class SonOverride extends  Father{
    @Override
    public void method() {
        System.out.println("AAA "+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("BBB "+Thread.currentThread().getName());
    }
}

運行結果:

很明顯這次運行結果是“異步的”,整個過程只間隔了一秒

倘若,我們在SonOverride中重寫的方法中加上“Synchronized”關鍵字的話

 @Override
    public synchronized void method() {

那麼運行結果:

可見效果跟直接繼承父類類似。

 

顯而易見,我們可以得出結論,加入父類方法中有synchronized關鍵字修飾,子類繼承該父類的方法也有Synchronizde關鍵字的效果,但是如果重寫該方法時不顯式加上synchronized關鍵字時則不會有效果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章