2017-02-23 37 views
0

我正在設計一個Objective-C中的單例類,它將被多個線程訪問。在我班有3-4 NSMutableArray,外班有閱讀,增加和刪除操作,這當然包裝在這個類中。在可變數組訪問中普遍使用@synchronized指令的替代方法

由於NSMutableArray不是線程安全的,我使用@synchronized()使我的操作線程安全,但它會導致使用@synchronized()塊過多。

因爲對於每個3-4陣列我至少有1個添加功能,1個刪除功能和5次我需要讀取值。所以,對於1個陣列,我至少使用了7個@synchronized()塊。 對於4個陣列,我需要在我的單例類中添加28個@synchronized

有沒有更好的方法來解決我的問題? 或者,如果我確實使用了所有這些@synchronized指令,是否會導致問題?

我知道如果我想讓我的對象線程安全,它會減慢我的代碼,但除此之外,還有什麼缺點?

+1

1)如果你的單例是線程安全的,那麼你可能不需要擔心它的數據成員_NSMutableArray_在你的情況。 2)您一定聽說過並使用過數據成員的_atomic/nonatomic_屬性。前者使他們線程安全。爲了額外的安全性,你可以聲明你的_NSMutableArrays_是原子的。 – Adeel

+1

另一種方法是爲每個陣列創建一個串行調度隊列。然後,您可以將數組更新同步分派到陣列更新方法中的相關隊列中。 @Adeel,使一個NSMutable數組屬性原子不會使底層數組線程安全,只是屬性本身。 – Paulw11

+1

@Adeel:對一個可變對象類型的屬性使用原子屬性確實不會同步變量。它不會使其「線程安全」。它只做一件事,一件事:確保吸氣劑和二道濾器不被打斷。對象之後發生的事情不受控制。 –

回答

2

通常它是而不是足以使原始調用(CRUD)同步以獲得線程安全性。這種精細的粒度級別只是基本的,但您還必須考慮更全球化的水平,並「大量」更多的代碼。如何做到這一點高度依賴於您的實際實施。多線程是邪惡的(tm),需要全面的觀點,所以對此沒有一般的答案。

同步塊通常會減慢應用程序的速度,至少如果它們被調用得太頻繁。有時最好將多個調用分組到一個同步塊中,以避免鎖定開銷。或者,如果呼叫很短,您可以使用自旋鎖,以防止不必要的任務暫停(請參閱here for an old question/answer)。

有關更多詳細信息,您可以查閱Apple documentation

+0

我是新的目標c,我在linux上工作,做旋轉鎖和目標c互斥體是否類似於pthread_mutex_lock?使用** synchronized **和pthread_mutex_lock會有一個折衷,因爲** synchronized **不會將代碼鎖定在同一個線程或函數堆棧中,其中pthread_mutex_lock可以鎖定在相同的線程和函數調用堆棧中。 **同步**還有另一個好處,你可以使用**返回**,只要你想在塊內,它就會自動解鎖。但是使用pthread_mutex_lock,如果你錯過了任何一個條件,它會讓你的生活變得糟糕。 –

+1

我認爲細節已經在這裏了:http://stackoverflow.com/questions/9463525/pthread-mutex-t-vs-synchronized-block - 旋轉鎖是非常不同的,因爲原因「積極」等待,只是在很短的通話時間推薦。 –

+0

感謝您的回答。我很遺憾,我忘了提及iOS的自旋鎖定是一個壞主意。我認爲對於我的場景,如您所說,遞歸互斥將更合適。 –

相關問題