我可以執行以下任何操作嗎?他們會正確鎖定/解鎖同一個對象嗎?爲什麼或者爲什麼不?假設有許多相同的線程使用全局變量「obj」,它在所有線程啓動之前被初始化。更改@synchronized節中的鎖定對象
1.
@synchronized(obj) {
[obj release];
obj = nil;
}
2.
@synchronized(obj) {
obj = [[NSObject new] autorelease];
}
我可以執行以下任何操作嗎?他們會正確鎖定/解鎖同一個對象嗎?爲什麼或者爲什麼不?假設有許多相同的線程使用全局變量「obj」,它在所有線程啓動之前被初始化。更改@synchronized節中的鎖定對象
1.
@synchronized(obj) {
[obj release];
obj = nil;
}
2.
@synchronized(obj) {
obj = [[NSObject new] autorelease];
}
簡短的回答:不,他們將無法正常鎖定/解鎖,並且應該避免這樣的方法。
我的第一個問題是爲什麼你想要這樣做,因爲這些方法首先無效使用@synchronized塊的目的和好處。
在第二個示例中,一旦線程更改了obj
的值,則到達@synchronized塊的每個後續線程將同步新對象而不是原始對象。對於N個線程,您將顯式創建N個自動釋放對象,並且運行時可能會創建多達N個與這些對象相關的遞歸鎖。換出臨界區域內同步的對象是線程安全併發的基本禁忌。不要這樣做。永遠。如果多個線程可以同時安全地訪問一個塊,只需完全省略@synchronized。
在你的第一個例子中,結果可能是未定義的,當然也不是你想要的結果。如果運行時只使用對象指針來查找關聯的鎖,那麼代碼可以正常運行,但在我的簡單測試中,nil
上的同步沒有可察覺的效果,所以您再次以無意義的方式使用@synchronized,因爲它不提供任何保護。
我老實說不想苛刻,因爲我認爲你可能只是對構造好奇。我只是強烈地表達(希望)能夠防止你和其他人編寫有致命缺陷的代碼,尤其是在假設它能夠正確同步的情況下。祝你好運!
注意:http://stackoverflow.com/questions/1215330/ – 2009-08-01 04:31:53
在閱讀完所有貼子後,我決定調查@synchronized更徹底一點,並寫一篇博客文章。您可能會覺得它很有用:http://rykap.com/objective-c/2015/05/09/synchronized.html – rjkaplan 2015-05-17 19:47:30