前言:在出現多線程競爭數據的時候往往離不開鎖,那么在這里給大家介紹下我們多線程同步技術的常用鎖?有下面這些
常用鎖如下:
?OSSpinLock
?os_unfair_lock
?pthread_mutex
?dispatch_semaphore
?dispatch_queue(DISPATCH_QUEUE_SERIAL)
?NSLock
?NSRecursiveLock
?NSCondition
?NSConditionLock
?@synchronized
1、OSSpinLock?
?OSSpinLock叫做”自旋鎖”,等待鎖的線程會處于忙等(busy-wait)狀態(tài),一直占用著CPU資源。
?目前已經不再安全,可能會出現優(yōu)先級反轉問題,如果等待鎖的線程優(yōu)先級較高,它會一直占用著CPU資源,優(yōu)先級低的線程就無法釋放鎖。這個鎖在ios10之后廢棄了,被os_unfair_lock替代。需要導入頭文件#import?
OSSpinLock代碼實現:

2、os_unfair_lock
?os_unfair_lock用于取代不安全的OSSpinLock?,從iOS10開始才支持
?從底層調用看,等待os_unfair_lock鎖的線程會處于休眠狀態(tài),并非忙等
?需要導入頭文件#import?
?用來取代之前的SpinLock,ios10之后才有的
代碼實現如下:

3、?pthread_mutex
?互斥鎖,等待鎖的線程會處于休眠狀態(tài)。
?需要導入頭文件#import?
跨平臺的鎖,在linux等其他平臺底層都通用
?PTHREAD_MUTEX_RECURSIVE遞歸鎖允許同一線程對鎖從復加鎖,不是同一線程不允許。
?PTHREAD_MUTEX_NORMAL普通鎖:不允許線程從復加鎖,要加鎖需要等鎖解鎖后才能再加。
(1)pthread_mutex?–?條件

4、NSLock、NSRecursiveLock
1)、NSLock是對mutex普通鎖的封裝,
?//創(chuàng)建鎖代碼
NSLock* lock = [[NSLock alloc]init];
2)、NSRecursiveLock也是對mutex遞歸鎖的封裝,API跟NSLock基本一致;


5、 NSCondition
?NSCondition是對mutex和cond的封裝
6、NSConditionLock

?NSConditionLock是對NSCondition的進一步封裝,可以設置具體的條件值

7、 dispatch_semaphore信號量
?信號量
?信號量的初始值,可以用來控制線程并發(fā)訪問的最大數量
?信號量的初始值為1,代表同時只允許1條線程訪問資源,保證線程同步

?8、 dispatch_queue實現線程同步
?直接使用GCD的串行隊列可以實現線程同步的
dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_SERIAL);
? ? dispatch_sync(queue, ^{
? ? ? ? //同步實現的邏輯任務
? ? });
9、?@synchronized
?@synchronized是對mutex遞歸鎖的封裝
?源碼查看:objc4中的objc-sync.mm文件
?@synchronized(obj)內部會生成obj對應的遞歸鎖,然后進行加鎖、解鎖操作。相當于obj作為key,生成一個遞歸鎖value。存在一個哈希表中。
實現代碼:
@synchronized(obj對象){
? ? ? ? //任務...
? ? }
? ? @synchronized(self){
? ? ? ? //任務...
? ? }
10、iOS線程同步方案性能比較
上面介紹了常用鎖的使用,那么性能上面比較,我們平時該怎么選擇使用呢?
?性能從高到低排序
--os_unfair_lock?? ios10之后新出的,版本有兼容要求。
--OSSpinLock???? ios10廢棄了,存在優(yōu)先級反轉的問題。
--dispatch_semaphore?? 推薦使用
--pthread_mutex?? 推薦使用
--dispatch_queue(DISPATCH_QUEUE_SERIAL)
--NSLock
--NSCondition
--pthread_mutex(recursive)
--NSRecursiveLock
--NSConditionLock
--@synchronized?? 性能最差不推薦使用。
11、自旋鎖、互斥鎖比較?
目前的鎖大體分為:自旋鎖跟互斥鎖,如果在沒有獲得鎖的情況下自旋鎖的線程不會進入休眠,處于忙等,互斥鎖會進入休眠。
1)什么情況使用自旋鎖比較劃算?
(1)預計線程等待鎖的時間很短
(2)加鎖的代碼(臨界區(qū))經常被調用,但競爭情況很少發(fā)生
(3)CPU資源不緊張
(4)多核處理器
2)什么情況使用互斥鎖比較劃算?
(1)預計線程等待鎖的時間較長
(2)單核處理器
(3)臨界區(qū)有IO操作,IO是比較消耗CPU資源的。
(4)臨界區(qū)代碼復雜或者循環(huán)量大
(5)臨界區(qū)競爭非常激烈