Objective-C中鎖的幾種實(shí)現(xiàn)方式

鎖的意義就是為了防止在多線程(多任務(wù))的情況下對(duì)共享資源(臨界資源)的臟讀或者臟寫辆影。也可以理解為:用于執(zhí)行多線程操作時(shí)強(qiáng)行限制資源訪問(wèn)的同步機(jī)制徒像,即并發(fā)控制中保證互斥的要求,可以理解成它用于排除并發(fā)的一種策略蛙讥。

分類方式 分類
按鎖的粒度劃分 表級(jí)鎖锯蛀、行級(jí)鎖、頁(yè)級(jí)鎖
按鎖的級(jí)別劃分 共享鎖键菱、排他鎖
按加鎖方式劃分 自動(dòng)鎖谬墙、顯示鎖
按鎖的使用方式劃分 樂(lè)觀鎖、悲觀鎖
按操作劃分 DML鎖经备、DDL鎖
等等拭抬。。 等等侵蒙。造虎。
方式1 使用NSLock類
  • 該類分成了幾個(gè)子類:NSLock、NSConditionLock(條件鎖)纷闺、NSRecursiveLock(遞歸鎖)以及NSCondition算凿。
  • 類內(nèi)方法:
    tryLock:作用是嘗試獲取一個(gè)鎖,并且立刻返回Bool值犁功,YES表示獲取了鎖氓轰,NO表示沒(méi)有獲取鎖失敗。
    lockBeforeDate::作用是在某個(gè)時(shí)刻之前獲取鎖浸卦,如果獲取成功署鸡,則返回YES,NO表示獲取鎖失敗限嫌。
- (void)lockDemo1 {
    NSLock *myLock = [[NSLock alloc] init];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [myLock lock];
        NSLog(@"執(zhí)行鎖1");
        sleep(5);
        [myLock unlock];
        if ([myLock tryLock]) {
            NSLog(@"可以獲得鎖1");
        }else {
            NSLog(@"不可以獲得鎖1");
        }
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        if ([myLock tryLock]) {
            NSLog(@"---可以獲得鎖2");
        }else {
            NSLog(@"----不可以獲得所2");
        }
        [myLock lock];
        NSLog(@"執(zhí)行鎖2");
        [myLock unlock];
    });
}
方式2 使用@synchorize
  • 對(duì)于@synchorize指令中使用的testLock為該鎖標(biāo)示靴庆,只有標(biāo)示相同的時(shí)候才滿足鎖的效果。它的優(yōu)點(diǎn)是不用顯式地創(chuàng)建鎖怒医,便可以實(shí)現(xiàn)鎖的機(jī)制炉抒。但是它會(huì)隱式地添加異常處理程序來(lái)保護(hù)代碼,該程序在拋出異常的時(shí)候自動(dòng)釋放鎖稚叹。
- (void)lockDemo2 {
   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       @synchronized (self) {
           NSLog(@"執(zhí)行鎖1");
           sleep(5);
       }
   });
   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       sleep(1);
       @synchronized (self) {
           NSLog(@"執(zhí)行鎖2");
       }
   });
}
方式3 使用gcd
- (void)lockDemo3 {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"執(zhí)行鎖1");
        sleep(5);
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"執(zhí)行鎖2");
        dispatch_semaphore_signal(semaphore);
    });
}
方式4 使用phtread
- (void)lockDemo4 {

    __block pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, NULL);

    //線程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        pthread_mutex_lock(&mutex);
        NSLog(@"執(zhí)行鎖1");
        sleep(5);
        pthread_mutex_unlock(&mutex);
    });

    //線程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        pthread_mutex_lock(&mutex);
        NSLog(@"執(zhí)行鎖2");
        pthread_mutex_unlock(&mutex);
    });
}
方式5 OSSpinLock
- (void)lockDemo4 {

    OSSpinLock spinlock = OS_SPINLOCK_INIT;

    //線程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        OSSpinLockLock(&spinlock);
        NSLog(@"執(zhí)行鎖1");
        sleep(5);
        OSSpinLockUnlock(&spinlock);
    });

    //線程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);
        OSSpinLockLock(&spinlock);
        NSLog(@"執(zhí)行鎖2");
        OSSpinLockUnlock(&spinlock);
    });
}
同樣加鎖解鎖次數(shù)耗時(shí)結(jié)果比較:

OSSpinlock < pthread_mutex < NSLock+IMP < NSLock < @synchronized

  • 1焰薄、@synchronized
    內(nèi)部會(huì)創(chuàng)建一個(gè)異常捕獲的handler和其他內(nèi)部使用的鎖。由于內(nèi)部會(huì)添加異常處理扒袖,所以耗時(shí)塞茅。
  • 2、NSLock 和 NSLock+IMP
    兩個(gè)時(shí)間非常接近僚稿。他們是 pthread mutexes 封裝的,但是創(chuàng)建對(duì)象的時(shí)候需要額外的開銷蟀伸。
  • 3蚀同、pthread_mutex
    底層的API缅刽,性能比較高,處理能力不錯(cuò)蠢络。
  • 4衰猛、gcd
    系統(tǒng)封裝的C代碼效果比pthread好。
  • 5刹孔、OSSpinLock
    自旋鎖不進(jìn)入內(nèi)核啡省,僅僅是重新加載。如果自旋鎖占用的時(shí)間是極少的(通常是納秒級(jí)別的)性能還是比較高的髓霞,減少了系統(tǒng)的直接調(diào)用和上下文的切換卦睹。(因?yàn)閮?yōu)先級(jí)倒置問(wèn)題已經(jīng)棄用,此類已經(jīng)被os_unfair_lock所替)

耗時(shí)結(jié)果如下: synthorize > NSLock > pthread > gcd > os_unfair_lock >OSSPinLock

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末方库,一起剝皮案震驚了整個(gè)濱河市结序,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纵潦,老刑警劉巖徐鹤,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異邀层,居然都是意外死亡返敬,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門寥院,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)劲赠,“玉大人,你說(shuō)我怎么就攤上這事只磷【酰” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵钮追,是天一觀的道長(zhǎng)预厌。 經(jīng)常有香客問(wèn)我,道長(zhǎng)元媚,這世上最難降的妖魔是什么轧叽? 我笑而不...
    開封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮刊棕,結(jié)果婚禮上炭晒,老公的妹妹穿的比我還像新娘。我一直安慰自己甥角,他們只是感情好网严,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嗤无,像睡著了一般震束。 火紅的嫁衣襯著肌膚如雪怜庸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天垢村,我揣著相機(jī)與錄音割疾,去河邊找鬼。 笑死嘉栓,一個(gè)胖子當(dāng)著我的面吹牛宏榕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播侵佃,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼麻昼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了趣钱?” 一聲冷哼從身側(cè)響起涌献,我...
    開封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎首有,沒(méi)想到半個(gè)月后燕垃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡井联,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年卜壕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烙常。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轴捎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚕脏,到底是詐尸還是另有隱情侦副,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布驼鞭,位于F島的核電站秦驯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏挣棕。R本人自食惡果不足惜译隘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望洛心。 院中可真熱鬧固耘,春花似錦、人聲如沸词身。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至损敷,卻和暖如春户辫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗤锉。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留墓塌,地道東北人瘟忱。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像苫幢,于是被迫代替她去往敵國(guó)和親访诱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354