2015-11-20 94 views
0

它在this question靜態和非靜態同步

有同步的靜態方法和sync'ed非靜態方法

好之間沒有聯繫,這是非常簡單的說,但如果非靜態方法中的代碼調用靜態方法會怎麼樣?此線程是否同時保持靜態(與類關聯)和非靜態(與類的實例關聯)監視器?

+5

一般來說,當你從一個「同步」模塊輸入另一個模塊(在不同的對象上同步)時,你必須獲得兩個顯示器。(如果代碼的另一部分試圖以相反的順序獲取相同的兩臺顯示器,那麼會出現死鎖。) – biziclop

回答

2

該線程是否同時保持靜態(與類關聯)和 非靜態(與類的實例關聯)監視器?

是的,這是因爲,

按照Java Language Specification 8.4.3.6

對於類(靜態) 方法中,使用具有用於該方法的 類的Class對象相關聯的顯示器。對於實例方法,使用與此(調用方法的對象)關聯的監視器。

而後所有的2個監視器將單獨定義。

+0

您[引用JLS](http://docs.oracle.com/javase/specs/ jls/se7/html/jls-8.html#jls-8.4.3.6)。你當然應該這樣說,既要進行適當的歸因,以避免剽竊費用,並且要給你的答案增加分量,你應該使用報價格式來表示引用的文本。 – EJP

+0

照顧你的評論,謝謝你的反饋。 – Dish

+0

'根據Java語言規範8.4.3.6'沒有引用文本,不應該如此格式化。 – EJP

1

沒有「靜態同步」或「非靜態同步」之類的東西。這些想法隱藏了真正發生的事情。

此:

class Foobar { 
    static synchronized void mumble() { ... } 
} 

只是爲了寫這一條捷徑:

class Foobar { 
    static void mumble() { 
     synchronized(Foobar.class) { 
      ... 
     } 
    } 
} 

而且這樣的:

class Foobar { 
    synchronized void grumble() { ... } 
} 

只是爲了寫這一條捷徑:

class Foobar { 
    void grumble() { 
     synchronized(this) { 
      ... 
     } 
    } 
} 

談論「靜態同步」是沒有意義的,因爲同步是你對對象做的事情,並且沒有靜態對象這樣的事情。 Java中唯一可以是static的東西是變量和方法。


P.S.,要回答你的問題,

當一個線程進入一個synchronized塊或方法,它必須獲得指定對象上的鎖,如果線程不已經有對象鎖定。因此,如果f.grumble()在我上面的示例中調用mumble(),那麼線程在進入grumble()例程時必須首先獲得f的鎖定,然後在仍然保持該鎖定的同時還必須獲得Foobar.class的鎖定。