我在問這個問題只是爲了好奇,我知道做這種事情是愚蠢的。線程進入同步塊後我們可以改變鎖嗎?
public void doSomething()
{
synchronized(object_A){
count++;
average = count/total;
}
}
現在,讓我們說我有2個線程同時運行(調用函數DoSomething的()),而第一個線程已經進入塊,讓該行「算++」說,第二個線程被阻塞,等待鎖。
現在我試着做object_A = new LockObject()
(在另一個線程中)。現在線程1和線程2發生了什麼?
線程2是否會進入該塊?由於它已經執行了語句「synchronized(object_A)」,所以更改鎖是否太遲了?
線程1會在同步塊(假設線程1仍在塊中)時更改鎖嗎?
線程1不會更改鎖定。它保存由變量object_A引用的對象上的鎖;一旦它獲得鎖定,它會忘記變量。你甚至可以'synchronized(someMethod()){}' – ignis
關於線程2,我猜(但我可能是錯的)它仍然會爭奪第一個鎖。 [JLS 7](http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.19)說,1.表達式被評估,之後2.線程獲取鎖,但是3.當另一個線程持有鎖時,線程不能做2。因此,在我看來,線程2將不會重新讀取變量的引用,從而使變量賦值無效。 – ignis
無論如何,您應該知道這裏還有一個問題 - 如果變量賦值不是易失性的,並且在賦值後沒有發生同步,則變量賦值可能無效。這是因爲允許線程創建變量的本地副本,並且只需要更新volatile/synchronized上的本地副本。 – ignis