2011-09-30 48 views

回答

5

該線程仍將擁有原始someObject的監視器,直到同步塊結束。如果你能想象,有兩種方法,Monitor.enter(Object)Monitor.exit(Object)然後synchronized塊將採取行動是這樣的:

SomeObject tmp = someObject; 
Monitor.enter(tmp); 
try 
{ 
    someObject = new SomeObject(); 
    someObject.doSomething(); 
} 
finally 
{ 
    Monitor.exit(tmp); 
} 

section 14.19 of the JLS

synchronized語句時,首先計算表達式執行。

如果由於某種原因,表達式的求值突然完成,那麼出於同樣的原因,同步語句會突然完成。

否則,如果Expression的值爲null,則拋出NullPointerException。

否則,讓表達式的非空值爲V.執行線程鎖定與V相關的鎖。然後執行塊。如果該塊的執行正常完成,則該鎖被解鎖並且同步語句正常完成。如果由於某種原因塊的執行突然完成,則鎖定被解鎖,同步語句突然完成,原因相同。

注意評估只發生一次。

+0

但'someObject'正在reconstructed.Isn't以前的對象GCD我不明白線程如何將仍然持有鎖?對象超出範圍。 – Cratylus

+0

感謝您的寫作:) @ user384706:也許事實上線程持有該對象的鎖被垃圾收集器看到,因爲仍然存在對該對象的引用? – Bartvbl

+0

@ user384706:只是因爲'someObject'不再提及它並不意味着它被垃圾收集......實際上它不能在這個塊中。 –

1

我相信someObject以前實例被鎖定,您實例未鎖定。

3

鎖適用於對象,而不是變量。在someObject = new SomeObject();之後,變量someObject引用了一個新對象,該鎖仍舊在舊對象上。

再見和再見非常危險。

相關問題