2011-04-08 33 views
4

我想知道,如果我有一個需要同步的對象,它存在於代碼塊中的幾個(2-3)位置,添加更好(更快) @synchronized整個塊或每個對象發生之前?Objective-C:@synchronized optimal use

@synchronized (someObj) { 
[someObj removeAllObjects];   
} 

.. 

@synchronized (someObj) { 
[someObj addObject:[NSNumber numberWithInt:203]];  
} 

VS

@synchronized (someObj) { 

[someObj removeAllObjects]; 

... (potential a large block of code) 

[someObj addObject:[NSNumber numberWithInt:203]]; 

... (potential a large block of code)  
} 

對這個有什麼想法?

回答

13

傑里米普所說的全是真的。還有其他一些事情需要考慮。如果第一個代碼片段適合你,那麼你可以推斷你在(長塊代碼)期間不關心任何中間狀態。 (也就是說你不是,從讀取這個數組在@synchronized塊之外,對吧?)在這種情況下,你最好是分批處理需要同步的操作,並且一次完成所有操作。例如:

.. 
id objectToAdd = [NSNumber numberWithInt: 203];  
.. 

@synchronized (someObj) 
{ 
    [someObj removeAllObjects] 
    [someObj addObject:objectToAdd];  
} 

一般認沽:併發性和性能是通過減少多少次,你拿鎖,多久你持有它,當你持有它,一旦你已經把它做爲改善。在這個微不足道的例子中,沒有任何信息表明我們不能使用這個鎖而不是兩次,而且也沒有跡象表明我們不能像上面那樣對這些操作進行批處理,並且明確地將所有不需要同步的代碼保留在同步塊。

這就是說:「讓它工作,讓它工作正確,讓它工作得很快。」 - 以該順序。我不會浪費大量的時間/精力來優化您的鎖定策略,直到您衡量您的應用並看到鎖爭用是一個問題。

+6

對於「使其工作正常;使其正確工作;使其工作得更快」。 – 2011-04-08 17:01:44

+0

讓它工作並使其正確工作應該是同一件事。然後讓它工作得很快。 – 2013-03-17 08:16:44

+1

根據我的經驗,每個軟件項目都有一個「第一次工作逼近」時刻,與「時間優化」時刻截然不同。你可以爭辯說,前一刻是無關的,但我注意到,如果沒有其他人,這往往是開發人員的重要時刻。作爲這個抽象事件存在的證據,我向你推薦你曾經使用過的每一半的垃圾軟件。 :) – ipmcc 2013-03-17 12:01:45

6

對此有何看法?

是的。

你只能通過性能分析來判斷,即測量它。

顯然釋放並重新獲取鎖定是一個性能問題,但請記住,塊中的所有代碼都是單線程的。因此,在多CPU /內核機器上,如果兩個線程都嘗試執行相同的同步塊,則將失去擁有多個內核和多個線程的優勢。

說了上面的話,我的直覺就是去尋找多個小的時鐘塊。實際上,在您給出的示例中,我會使方法-removeAllObjects-addObject:同步,而不是嘗試記住始終將它們放在調用方法的同步塊中。