2009-08-01 62 views
6

我可以執行以下任何操作嗎?他們會正確鎖定/解鎖同一個對象嗎?爲什麼或者爲什麼不?假設有許多相同的線程使用全局變量「obj」,它在所有線程啓動之前被初始化。更改@synchronized節中的鎖定對象

1.

@synchronized(obj) { 
    [obj release]; 
    obj = nil; 
} 

2.

@synchronized(obj) { 
    obj = [[NSObject new] autorelease]; 
} 
+0

注意:http://stackoverflow.com/questions/1215330/ – 2009-08-01 04:31:53

+1

在閱讀完所有貼子後,我決定調查@synchronized更徹底一點,並寫一篇博客文章。您可能會覺得它很有用:http://rykap.com/objective-c/2015/05/09/synchronized.html – rjkaplan 2015-05-17 19:47:30

回答

8

簡短的回答:不,他們將無法正常鎖定/解鎖,並且應該避免這樣的方法。

我的第一個問題是爲什麼你想要這樣做,因爲這些方法首先無效使用@synchronized塊的目的和好處。

在第二個示例中,一旦線程更改了obj的值,則到達@synchronized塊的每個後續線程將同步新對象而不是原始對象。對於N個線程,您將顯式創建N個自動釋放對象,並且運行時可能會創建多達N個與這些對象相關的遞歸鎖。換出臨界區域內同步的對象是線程安全併發的基本禁忌。不要這樣做。永遠。如果多個線程可以同時安全地訪問一個塊,只需完全省略@synchronized。

在你的第一個例子中,結果可能是未定義的,當然也不是你想要的結果。如果運行時只使用對象指針來查找關聯的鎖,那麼代碼可以正常運行,但在我的簡單測試中,nil上的同步沒有可察覺的效果,所以您再次以無意義的方式使用@synchronized,因爲它不提供任何保護。

我老實說不想苛刻,因爲我認爲你可能只是對構造好奇。我只是強烈地表達(希望)能夠防止你和其他人編寫有致命缺陷的代碼,尤其是在假設它能夠正確同步的情況下。祝你好運!