2009-11-29 121 views
2

我只需要確認我已經正確理解了鎖定同步塊的概念。 首先我會告訴我所瞭解的。 獲取對象的鎖定意味着沒有其他線程可以訪問對象類的同步代碼。在同步方法的情況下,線程獲取用於調用該方法的對象的鎖定(即,隱式地引用該引用)。這意味着其他線程無法訪問當前對象的類的同步代碼。但是,在同步塊的情況下,我們可以指定我們希望線程獲取鎖的對象。同步塊鎖定

現在讓我們說我們的方法中的在A類同步塊獲取鎖類B的對象因此,可以說一個線程進入該同步塊,並已獲得B類的特定對象的鎖

如果任何其他線程使用B類的同一對象,它將無法在類A中輸入同步塊,對嗎? 而且其他線程也不能訪問類B中的任何同步代碼?

那麼A類中的其他同步代碼呢?由於線程已獲得對類B的對象的鎖,其他線程可以訪問類A的另一個同步代碼嗎?這意味着A類的對象沒有鎖定,只有B類?

我希望人們瞭解我的問題。

在此先感謝。

+1

就類而言,類是不相關的(不幸的是,靜態方法標記爲'Class'對象上的同步鎖--DH)。把鎖想象成另一個對象,每個對象都帶有一個最終引用(這是一個糟糕的設計!),鎖定一個對象並不意味着不打擾鎖的代碼無法訪問該對象的字段。 – 2009-11-29 07:43:46

回答

1

首先,我認爲你最好不要在課堂上講課。假設您有兩個對象o1o2,這些對象實際上與討論無關,並且o1o2有參考。

如果o1同步實例o2上的塊,則其他線程不能在同一實例o2上進入同步節。這可能是一個非靜態的同步方法o2或任何請求在同一對象上鎖定的同步塊(假設有一個o3對象,該對象也具有對o2的引用,並且想要同步它,它將被阻止,直到o1釋放鎖)。

可能會讓您困惑的是圍繞同步方法的語法糖。同步方法只是一種方法,編譯器會在調用該方法的實際實例上添加一個同步塊,該方法涵蓋整個方法體。

public synchronized void synch1() { 
    // body 
} 
// equivalent to: 
public void synch2() { 
    synchronized(this) { 
     // body 
    } 
} 

如果你總是用同步塊和被用作鎖的實際實例來思考,事情在我看來更簡單。一個線程可以鎖定任何對象,兩個線程無法訪問同一個對象鎖定的同步區域。

2

獲取 對象的鎖定裝置,沒有其他線程可以 訪問 對象的類的同步代碼。

這並非嚴格對稱。如果代碼在不同的對象實例上同步,則另一個線程可以執行屬於對象類的同步代碼。該鎖僅限制正在同一實例上同步的線程。現在

,如果你正在談論的同步(非靜態)方法,那麼就會被鎖定的對象是this的調用方法。但是同樣的規則適用。

現在讓我們說我們在類A中的方法獲取 上類B的對象所以讓 說一個線程進入此 同步塊,並已獲得 特定的鎖定的鎖定同步塊 類B.

如果任何其他線程使用類B的相同 對象時,它將不能 在 類A進入同步塊,右邊的對象?並且其他 線程也不能訪問類B中的任何 同步代碼?

如果「其他線程」在B的同一實例上同步,則第一部分是正確的,否則它是不正確的。

第二部分是不正確的。它只是在被阻塞的B的同一實例上同步的代碼。

+0

「這只是在被阻止的B的同一實例上同步的代碼。」 所以,你的意思是類B的對象上同步的類A中的代碼將被阻塞。如果B類本身具有同步代碼,它不會被阻止?我有這個問題,因爲它是我們獲得的B類對象的鎖。該鎖應該阻止同步代碼在calss B也。不是嗎? – TheCoolestSid 2009-11-29 07:44:56

+1

不,我的意思是隻有在同一個B對象上同步時纔會被阻塞。關鍵是代碼的位置是不相關的; *唯一重要的*是您正在同步的對象。 – 2009-11-29 07:54:32

+0

好的。因此,如果一個線程獲得了對象的鎖定,那麼在該對象上同步的所有代碼都將被阻塞,無論代碼在哪裏。 – TheCoolestSid 2009-11-29 07:58:32