synchronized爲什麼不能繼承?

synchronized的常見使用方式

修飾代碼塊(同步代碼塊)

synchronized (object) {
      //具體代碼
}

修飾方法

synchronized void test(){
  //具體代碼
}

synchronized不能繼承?(插曲)

父類A:

public class A {
    synchronized void test() throws Exception {
        try {
            System.out.println("main 下一步 sleep begin threadName="
                    + Thread.currentThread().getName() + " time="
                    + System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("main 下一步 sleep end threadName="
                    + Thread.currentThread().getName() + " time="
                    + System.currentTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

子類B:(未重寫test方法)

public class B extends A {

}

子類C:(重寫test方法)

public class C extends A {

    @Override
     void test() throws Exception{
        try {
            System.out.println("sub 下一步 sleep begin threadName="
                    + Thread.currentThread().getName() + " time="
                    + System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("sub 下一步 sleep end threadName="
                    + Thread.currentThread().getName() + " time="
                    + System.currentTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
} 

 

線程A:

public class ThreadA extends Thread {
    private A a;

    public void setter  (A a) {
        this.a = a;
    }

    @Override
    public void run() {
        try{
            a.test();
        }catch (Exception e){

        }
    }
}

線程B:

public class ThreadB extends Thread {
    private B b;
    public void setB(B b){
        this.b=b;
    }

    @Override
    public void run() {
        try{
            b.test();
        }catch (Exception e){

        }
    }
} 

 

線程C:

public class ThreadC extends Thread{
    private C c;
    public void setC(C c){
        this.c=c;
    }

    @Override
    public void run() {
        try{
            c.test();
        }catch (Exception e){

        }
    }
}

測試類test:

public class test {
    public static void main(String[] args) throws Exception {
        A a = new A();
        ThreadA A1 = new ThreadA();
        A1.setter(a);
        A1.setName("A1");
        A1.start();
        ThreadA A2 = new ThreadA();
        A2.setter(a);
        A2.setName("A2");
        A2.start();
        A1.join();
        A2.join();

        System.out.println("=============");
        B b = new B();
        ThreadB B1 = new ThreadB();
        B1.setB(b);
        B1.setName("B1");
        B1.start();
        ThreadB B2 = new ThreadB();
        B2.setB(b);
        B2.setName("B2");
        B2.start();
        B1.join();
        B2.join();
        System.out.println("=============");

        C c = new C();
        ThreadC C1 = new ThreadC();
        C1.setName("C1");
        C1.setC(c);
        C1.start();
        ThreadC C2 = new ThreadC();
        C2.setName("C2");
        C2.setC(c);
        C2.start();
        C1.join();
        C2.join();
    }
}

 

運行結果:

子類B繼承了父類A,但是沒有重寫test方法,ThreadB仍然是同步的。子類C繼承了父類A,也重寫了test方法,但是未明確寫上synchronized,所以這個方法並不是同步方法。只有顯式的寫上synchronized關鍵字,纔是同步方法。

所以synchronized不能繼承這句話有歧義,我們只要記住子類如果想要重寫父類的同步方法,synchronized關鍵字一定要顯示寫出,否則無效。

修飾靜態方法

synchronized static void test(){
   //具體代碼
}

修飾類

 synchronized (Example2.class) {
    //具體代碼
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章