public class ObjectCounter {
private static long numOfInstances = 0;
public ObjectCounter(){
synchronized(this){
numOfInstances++;
}
}
**public static synchronized long getCount(){
return numOfInstances;
}**
//vs//
**public static long getCount(){
return numOfInstances;
}**
}
如果我將運行幾個線程,其中一些調用靜態函數getCount()
,其中一些創建新的實例。我想每次打電話給getCount()
當時的實例數。同步(this)只鎖定同步塊還是全部「this」代碼?
- 代碼中的兩個選項有區別嗎?
- 如果我鎖定「
this
」不應該意味着我不能調用getCount()
,直到構造函數退出同步塊(可以說我是否不在getCount()上同步)。 - 如果我在代碼的某個地方做了一個同步塊,它是否只鎖定同步塊或所有的「
this
」代碼? - 從這裏開始編輯:謝謝大家,這是非常有幫助的,但我有幾個問題,你的答案。
- 如果我理解正確,synchronized(this)塊不會影響(或連接到)靜態同步函數(以鎖定方式而不是numOfInstances增量)?
- 有沒有更好的選項來使增量和getCount()函數線程安全? (比如打開一個靜態對象並且同步(obj)而不是同步(this) - 朋友建議)。
- 如果我在ObjectCounter類中有一個f1()方法(非靜態),而一個線程在synchronized(this)中,其他線程可以進入f1()塊(不是同步類還是內部有同步塊)?
- 如果我在ObjectCounter中有一個f1()方法(非靜態)和f2()方法(非靜態),在f1()中我已經同步(this)塊。當一個線程在同步(this)塊中時,其他線程是否可以輸入f1()塊(不是同步類或內部有同步塊)? (允許在同一個實例說兩個線程「工作」的)
`
您絕不允許調用實例方法(例如,在該實例的構造函數返回之前,任何對象的'getCount()')。唯一可能的方式是如果構造函數將'this'發佈到另一個線程。 (也被稱爲「從構造函數泄漏_this_」)。如果你認爲你必須在構造函數中寫入'synchronized(this)',那麼你可能犯了一個巨大的錯誤。 –
請在您對問題得到正確和完整的答案後,不要編輯您的問題以添加更多問題(或者更糟糕的是,替換您現有的問題)。爲此提出一個新問題,或對後續問題的正確答案發表評論。 – Buurman
所有的答案都非常好,很有幫助,但是我只能選擇一個幫助我的人,而且我認爲只選擇一個並不公平。如果這是必須的,我會選擇一個。 –