2013-04-14 83 views
28

我有超類Point和​​方法draw()Point的子類會繼承​​如果我覆蓋方法draw()在他們或我必須始終寫它?同步在Java中繼承嗎?

+0

的[重寫同步可能重複方法](http://stackoverflow.com/questions/10173345/overriding-a-synchronized-method) – Raedwald

回答

28

不,您將永遠必須編寫​​。如果你調用超類的synchronized方法,這當然是一個同步調用。​​不是方法簽名的一部分。

請參閱http://gee.cs.oswego.edu/dl/cpj/mechanics.html以獲取來自Java線程老大(或多或少)的Doug Lea的詳細描述。

+2

也許可以澄清一個細節:給定的方法調用是否同步取決於它所調用的對象的動態類型,而不是靜態類型。也就是說,如果'Derived'中的'foo()'是'synchronized'而不是'Base'中的'synchronized',並且將'Derived'分配給'Base'變量並且調用'foo()',那麼這個調用將會同步。這點在語言規範的8.4.3.6中是隱含的(它說「synchronized」方法等同於該方法中的synchronized語句),但是我找不到它在其他地方拼寫出來。 Runnable演示[這裏](http://runnable.com/U4zBThIj5WNju2g2/)。 – mrec

4

您的Overriden方法將不再同步如果您覆寫並刪除​​。找到它herehere

+1

您的引用都不是規範性參考。 – EJP

10

您可以通過編寫此檢查自己:

public class Shape { 

    protected int sum = 0; 

    public synchronized void add(int x) { 
     sum += x; 
    } 
} 


public class Point extends Shape{ 

    public void add(int x) { 
     sum += x; 
    } 

    public int getSum() { 
     return sum; 
    } 
} 

和測試類

public class TestShapes { 

    public final static int ITERATIONS = 100000; 

    public static void main(String[] args) throws InterruptedException { 

     final Point p = new Point(); 

     Thread t1 = new Thread(){ 
      @Override 
      public void run() { 

       for(int i=0; i< ITERATIONS; i++){ 
        p.add(1); 
       } 
      } 
     }; 

     Thread t2 = new Thread(){ 
      @Override 
      public void run() { 

       for(int i=0; i< ITERATIONS; i++){ 
        p.add(1); 
       } 
      } 
     }; 

     t1.start(); 
     t2.start(); 

     t1.join(); 
     t2.join(); 


     System.out.println(p.getSum()); // should equal 200000 

    } 
} 

在我的機器是137099,而不是200000

+2

更簡單的測試方法是測試['Thread.holdsLock(this);'](http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#holdsLock% 28java.lang.Object%29)在重寫的方法 –

+4

不回答問題。測試代碼可能因爲除了同步以外的事情而暴露出錯誤或時間異常。答案可以在語言規範中找到。 – EJP

+0

@EJP起初我以爲你錯了。然後我意識到你確實是對的,但相當悲觀...... – Timo