iOS鎖系列-NSLock對象鎖

原文,本文只為學(xué)習(xí)

對象鎖:代碼為[臨界區(qū):共同訪問一段代碼]synchronized(Object)語句指定的對象進(jìn)行加鎖

示例:

//主線程中
    NSLock *lock = [[NSLock alloc] init];
    
    //線程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [lock lock];
        NSLog(@"線程1");
        sleep(2);
        [lock unlock];
        NSLog(@"線程1解鎖成功");
    });

    //線程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);//以保證讓線程2的代碼后執(zhí)行
        [lock lock];
        NSLog(@"線程2");
        [lock unlock];
    });

2016-08-19 14:23:09.659 ThreadLockControlDemo[1754:129663] 線程1
2016-08-19 14:23:11.663 ThreadLockControlDemo[1754:129663] 線程1解鎖成功
2016-08-19 14:23:11.665 ThreadLockControlDemo[1754:129659] 線程2

NSLock的執(zhí)行原理:
線程 1 中的 lock 鎖上了闷祥,所以線程 2 中的 lock 加鎖失敗傲诵,阻塞線程 2拴竹,但 2 s 后線程 1 中的 lock 解鎖,線程 2 就立即加鎖成功座泳,執(zhí)行線程 2 中的后續(xù)代碼。

查到的資料顯示互斥鎖會使得線程阻塞挑势,阻塞的過程又分兩個階段潮饱,第一階段是會先空轉(zhuǎn),可以理解成跑一個 while 循環(huán)啦扬,不斷地去申請加鎖缕溉,在空轉(zhuǎn)一定時間之后证鸥,線程會進(jìn)入 waiting 狀態(tài),此時線程就不占用CPU資源了泉褐,等鎖可用的時候鸟蜡,這個線程會立即被喚醒揉忘。

所以如果將上面線程 1 中的 sleep(2); 改成 sleep(10); 輸出的結(jié)果會變成

2016-08-19 14:25:16.226 ThreadLockControlDemo[1773:131824] 線程1
2016-08-19 14:25:26.231 ThreadLockControlDemo[1773:131831] 線程2
2016-08-19 14:25:26.231 ThreadLockControlDemo[1773:131824] 線程1解鎖成功

從上面的兩個輸出結(jié)果可以看出泣矛,線程 2 lock 的第一秒您朽,是一直在輪詢請求加鎖的,因為輪詢有時間間隔哗总,所以 ”線程 2“ 的輸出晚于 ”線程 1 解鎖成功“讯屈,但線程 2 lock 的第九秒,是當(dāng)鎖可用的時候具壮,立即被喚醒,所以 ”線程 2“ 的輸出早于 ”線程 1 解鎖成功“。多做了幾次試驗炮赦,發(fā)現(xiàn)輪詢 1 秒之后,線程會進(jìn)入 waiting 狀態(tài)性芬。

//主線程中
    NSLock *lock = [[NSLock alloc] init];
    
    //線程1
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [lock lock];
        NSLog(@"線程1");
        sleep(10);
        [lock unlock];
    });
    
    //線程2
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1);//以保證讓線程2的代碼后執(zhí)行
        if ([lock tryLock]) { //嘗試加鎖
            NSLog(@"線程2");
            [lock unlock];
        } else {
            NSLog(@"嘗試加鎖失敗");
        }
    });

2016-08-19 11:42:54.433 ThreadLockControlDemo[1256:56857] 線程1
2016-08-19 11:42:55.434 ThreadLockControlDemo[1256:56861] 嘗試加鎖失敗

由上面的結(jié)果可得知植锉,tryLock 并不會阻塞線程俊庇。[lock tryLock] 能加鎖返回 YES辉饱,不能加鎖返回 NO彭沼,然后都會執(zhí)行后續(xù)代碼姓惑。

如果將 [lock tryLock] 替換成

[lock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:10]

的話于毙,則會返回 YES乘寒,輸出 “線程 2“,lockBeforeDate: 方法會在所指定 Date 之前嘗試加鎖烂翰,會阻塞線程甘耿,如果在指定時間之前都不能加鎖佳恬,則返回 NO捏境,指定時間之前能加鎖垫言,則返回 YES筷频。

@protocol NSLocking

- (void)lock;//加鎖
- (void)unlock;//解鎖

@end

@interface NSLock : NSObject <NSLocking> {
@private
    void *_priv;
}

//嘗試加鎖凛捏,不會阻塞線程坯癣。true則加鎖成功示罗,false則失敗窒所,說明其他線程在加鎖中這個方法無論如何都會立即返回吵取。
- (BOOL)tryLock;

//嘗試在指定NSDate之前加鎖,會阻塞線程脯倒。true則加鎖成功,false則失敗捺氢,說明其他線程在加鎖中這個方法無論如何都會立即返回藻丢。在拿不到鎖時不會一直在那等待。
- (BOOL)lockBeforeDate:(NSDate *)limit;

//name 是用來標(biāo)識用的
@property (nullable, copy) NSString *name API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));

@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末摄乒,一起剝皮案震驚了整個濱河市悠反,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌馍佑,老刑警劉巖斋否,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拭荤,居然都是意外死亡茵臭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門舅世,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旦委,“玉大人,你說我怎么就攤上這事摩钙。” “怎么了翎碑?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我填硕,道長,這世上最難降的妖魔是什么姻檀? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任杂抽,我火速辦了婚禮,結(jié)果婚禮上匙睹,老公的妹妹穿的比我還像新娘。我一直安慰自己丘跌,他們只是感情好荒澡,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般慢睡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上者吁,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天育八,我揣著相機(jī)與錄音,去河邊找鬼膳犹。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播耘分,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼芽丹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了懈涛?” 一聲冷哼從身側(cè)響起得封,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤腰懂,失蹤者是張志新(化名)和其女友劉穎涮毫,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡绽昼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年柿估,在試婚紗的時候發(fā)現(xiàn)自己被綠了只厘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赋元。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡嫡良,死狀恐怖京闰,靈堂內(nèi)的尸體忽然破棺而出捐迫,到底是詐尸還是另有隱情雷则,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布猜揪,位于F島的核電站钧萍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏万搔。R本人自食惡果不足惜蟹略,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一意敛、第九天 我趴在偏房一處隱蔽的房頂上張望撩独。 院中可真熱鬧综膀,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至手蝎,卻和暖如春榕莺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棵介。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工钉鸯, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人邮辽。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓唠雕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親吨述。 傳聞我的和親對象是個殘疾皇子岩睁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容