2017-04-16 73 views
0

這個問題來自Java實踐中的併發實例。在本書的第二章中,我們得到了一個這樣的例子,我沒有完全複製它。比方說,我們的代碼同步方法override-線程獲取鎖定哪個對象?

class A{ 
synchronized void method1(){ 
    do some stuff.. 
    } 
} 
class B extends A{ 
    synchronized void method1(){ 
    super.method1(); 
    } 
} 

以下塊現在我們創建B類的一個對象,並做下面的事情,這正好在公共靜態無效的主要。

B b=new B() 
Thread t1=new Thread(new Runnable() { 

     @Override 
     public void run() { 
      // TODO Auto-generated method stub 
      b.method1(); 
     } 
    }); 
Thread t2=new Thread(new Runnable() { 

     @Override 
     public void run() { 
      // TODO Auto-generated method stub 
      b.method1(); 
     } 
    }); 

而隨後啓動的t1和t2的線程。

這裏,我的問題是

  1. 正如我在這裏同步方法對哪些對象線程獲得鎖?我只創建對象B和B的「方法一」我能想到的線程獲取關於B對象的鎖,但在執行以下代碼

    super.method1()

和控制隨後達到超類的方法1在哪個對象上獲取鎖?因爲我沒有創建任何A級對象。

  1. 而這種行爲又如何與Reentrancy相關?
+0

如何發佈實際編譯的代碼?沒有什麼能夠讓你的線程調用'method1',或者確實使用'B'的實例。這反過來掩蓋了你的問題,所以它不知道你在問什麼,也不可能回答。 –

+0

道歉,更正。 –

+0

不包括分號。你真的編譯和運行你發佈的代碼嗎? –

回答

1

因爲只有一個B的實例,所以它的監視器將被獲取。

super.method1()調用還會獲取監視器(重新插入)。該對象仍然爲B,由於仍然從this(即相同的確切實例)獲取監視器,所以該方法在超類中定義沒有區別。

+0

但是發佈的代碼沒有顯示任何線程訪問任何'B'的實例。 –

+1

我學會了忽視發佈的代碼,只是推斷信息。 – Kayaman

+0

我學到了相反的情況。我無法計算我職業生涯中因爲「推斷」(猜測)錯誤而被擊落的次數。它是軟件工程的一部分,提供並要求明確,明確的要求。 –