有同步的靜態方法和sync'ed非靜態方法
好之間沒有聯繫,這是非常簡單的說,但如果非靜態方法中的代碼調用靜態方法會怎麼樣?此線程是否同時保持靜態(與類關聯)和非靜態(與類的實例關聯)監視器?
有同步的靜態方法和sync'ed非靜態方法
好之間沒有聯繫,這是非常簡單的說,但如果非靜態方法中的代碼調用靜態方法會怎麼樣?此線程是否同時保持靜態(與類關聯)和非靜態(與類的實例關聯)監視器?
該線程是否同時保持靜態(與類關聯)和 非靜態(與類的實例關聯)監視器?
是的,這是因爲,
按照Java Language Specification 8.4.3.6,
對於類(靜態) 方法中,使用具有用於該方法的 類的Class對象相關聯的顯示器。對於實例方法,使用與此(調用方法的對象)關聯的監視器。
而後所有的2個監視器將單獨定義。
沒有「靜態同步」或「非靜態同步」之類的東西。這些想法隱藏了真正發生的事情。
此:
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
的鎖定。
一般來說,當你從一個「同步」模塊輸入另一個模塊(在不同的對象上同步)時,你必須獲得兩個顯示器。(如果代碼的另一部分試圖以相反的順序獲取相同的兩臺顯示器,那麼會出現死鎖。) – biziclop