線程安全的概念是,當多個線程同時訪問一個資源時,要確保資源的準確性。也就是說,多個線程必須同步訪問一塊資源……安全
實現線程安全就是加鎖。加鎖,鎖定的代碼要儘可能少。加鎖範圍內的代碼,同一時間只容許一個線程執行。互斥鎖@synchronized (self)的參數,任何繼承NSObject的對象均可以,如:self。要保證這個鎖對象,全部的線程都能訪問到,並且全部線程訪問的是同一個鎖對象。多線程
線程實現同步的兩種鎖:(互斥鎖與自旋鎖的概念在「區別」中有定義)性能
1,互斥鎖atom
2,自旋鎖線程
共同點:設計
可以鎖定一段代碼,同一時間,只有一個線程可以執行這段鎖定的代碼。code
區別:對象
互斥鎖:在鎖定的時候,其餘線程會進入睡眠狀態,等待條件知足時,從新喚醒。(當A線程在線程池中,CUP進行處理時,其餘線程會從線程池出來,進入睡眠狀態,等待喚醒)繼承
自旋鎖:在鎖定的時候,其餘線程會進入一個死循環,也是一直在等待條件知足,一旦條件知足,當即執行,少了一個喚醒過程。(當A線程在線程池中,CPU進行處理時,其餘線程還在線程池裏面)資源
就由於自旋鎖少了一個喚醒線程的過程,因此自旋鎖的效率要比互斥鎖高那麼一點點。所以咱們在鎖定一段代碼時,寫@synchronized(self){}的時候,在Xcode中並不會有提示,緣由是蘋果不推薦加鎖,加鎖性能太差!
在定義屬性時,如:@property(atomic, strong) NSObject *obj; 其關鍵字atomic爲原子性,(默認的屬性就爲原子屬性),原子性就是爲多線程設計的,原子性實現單(線程)寫多(線程)讀。由於寫的安全級別要求更高,讀的要求低一些,能夠多讀幾回確保數據的正確性。
在下面重寫了setter和getter方法:若是同時重寫了setter方法和getter方法,「_成員變量」就不會提供,就可使用合成指令@synthesize,告訴編譯器屬性成員變量的名稱:
@synthesize obj = _obj;
- (void)setObj:(NSObject *)obj
{
@synchronized (self){ //模擬鎖。真實狀況下,使用的不是互斥鎖。原子屬性內部使用的是自旋鎖……
_obj = obj;
}
}
- (NSObject *)Obj
{
return _obj;
}
UI線程,咱們通常可稱爲主線程。UIKit中絕大部分類,都不是「線程安全」的。怎麼解決這個線程不安全的問題?蘋果約定,全部程序更新UI都在主線程中進行,也就不會出現多個線程同時改變一個資源。
在主線程中更新UI,有什麼好處?
1,在主線程中更新UI,就不會出現多個線程同時改變同一個UI控件。
2,主線程優先級最高,也就意味着UI的更新優先級高,讓用戶感受運行很流暢。