2015-04-05 23 views
1

以下方法是SomeType類的方法 - 它用作其參數的類型。 行註釋表示行#s。方法調用和同步塊之間的「間隙」 - 避免併發中的死鎖

synchronized void someMethod(SomeType other) { // line 1 
           // line 2 
    synchronized (other) {  // line 3 
     //...do stuff   // line 4 
    } 
} 

塊表示爲「線4」具有的兩個thisother一些其他同步方法調用,並且該代碼是用於避免死鎖。

但是 - 假設同時調用a.someMethod(b)b.someMethod(a),其中ab是不同的實例。

進一步假設b.someMethod(a)被調用後立即a.someMethod(b)是,他們都在行2--每個ab獲得自己的鎖,並等待對方的鎖進行舉起 。

這可能發生嗎?

如果是這樣 - 在哪個jdk實現?這看起來像取決於具體實現的東西,除非它明確地在jdk規範中。

TIA

+2

但'b'可以在*'a'進入第3行的塊之前進入'someMethod()'*。每個線程都擁有頂級監視器並且處於死鎖狀態。 – chrylis 2015-04-05 20:54:22

+0

當然,看起來像是一個僵局。我見過的常用方法是始終以明確的順序獲取互斥鎖。 – chrylis 2015-04-05 20:54:57

+0

@chrylis好的,我的錯。 – 2015-04-05 20:56:03

回答

1

是的,你描述的死鎖可能會發生。它發生的頻率可能取決於線程代碼的細節;現在,您很可能使用操作系統的本地線程,所以它更依賴於本機操作系統而不是JDK/JRE。儘管在大多數平臺上可能會出現死鎖,所以您應該在代碼中防範它。

如果您認爲該方法的爭用會很低或者您不關心性能,則可以在靜態成員或類本身上進行同步,而不是在對象上同步。如果您關心性能並認爲爭用會很大,那麼您需要找出一種方法來確保監視器被鎖定在相同的順序,而不管調用方法的哪個對象以及哪個方法參數。