iOS中的鎖

使用NSLock實(shí)現(xiàn)的鎖

? ? ? ?NSLock是Cocoa提供給我們最基本的鎖對(duì)象款熬,這也是我們經(jīng)常所使用的哪轿,除lock和unlock方法外坷襟,NSLock還提供了tryLock和lockBeforeDate:兩個(gè)方法撤嫩,前一個(gè)方法會(huì)嘗試加鎖,如果鎖不可用(已經(jīng)被鎖住)鹉梨,剛并不會(huì)阻塞線程讳癌,并返回NO。lockBeforeDate:方法會(huì)在所指定Date之前嘗試加鎖存皂,如果在指定時(shí)間之前都不能加鎖晌坤,則返回NO逢艘。


NSLock.png

使用synchronized關(guān)鍵字構(gòu)建的鎖

? ? ? ?@synchronized指令使用的obj為該鎖的唯一標(biāo)識(shí),只有當(dāng)標(biāo)識(shí)相同時(shí)骤菠,才為滿足互斥它改,如果線程2中的@synchronized(obj)改為@synchronized(other),剛線程2就不會(huì)被阻塞,@synchronized指令實(shí)現(xiàn)鎖的優(yōu)點(diǎn)就是我們不需要在代碼中顯式的創(chuàng)建鎖對(duì)象商乎,便可以實(shí)現(xiàn)鎖的機(jī)制央拖,但作為一種預(yù)防措施,@synchronized塊會(huì)隱式的添加一個(gè)異常處理例程來(lái)保護(hù)代碼鹉戚,該處理例程會(huì)在異常拋出的時(shí)候自動(dòng)的釋放互斥鎖鲜戒。所以如果不想讓隱式的異常處理例程帶來(lái)額外的開銷,你可以考慮使用鎖對(duì)象抹凳。

synchronized.png

使用GCD來(lái)實(shí)現(xiàn)的”鎖”

? ? ? ? 以上代碼構(gòu)建多線程我們就已經(jīng)用到了GCD的dispatch_async方法袍啡,其實(shí)在GCD中也已經(jīng)提供了一種信號(hào)機(jī)制,使用它我們也可以來(lái)構(gòu)建一把”鎖”(從本質(zhì)意義上講却桶,信號(hào)量與鎖是有區(qū)別境输,具體差異參加信號(hào)量與互斥鎖之間的區(qū)別):


Semaphore.png

NSRecursiveLock遞歸鎖

? ? ? ? NSRecursiveLock實(shí)際上定義的是一個(gè)遞歸鎖,這個(gè)鎖可以被同一線程多次請(qǐng)求颖系,而不會(huì)引起死鎖嗅剖。這主要是用在循環(huán)或遞歸操作中。我們先來(lái)看一個(gè)示例:

死鎖.png

? ? ? ? 這段代碼是一個(gè)典型的死鎖情況嘁扼。在我們的線程中信粮,RecursiveMethod是遞歸調(diào)用的。所以每次進(jìn)入這個(gè)block時(shí)趁啸,都會(huì)去加一次鎖强缘,而從第二次開始,由于鎖已經(jīng)被使用了且沒(méi)有解鎖不傅,所以它需要等待鎖被解除旅掂,這樣就導(dǎo)致了死鎖,線程被阻塞住了访娶。調(diào)試器中會(huì)輸出如下信息:

value = 5

***?-[NSLock?lock]:?deadlock?('(null)')???***?Break?on?_NSLockError()?to?debug.

? ? ? ? 在這種情況下商虐,我們就可以使用NSRecursiveLock。它可以允許同一線程多次加鎖崖疤,而不會(huì)造成死鎖秘车。遞歸鎖會(huì)跟蹤它被lock的次數(shù)。每次成功的lock都必須平衡調(diào)用unlock操作劫哼。只有所有達(dá)到這種平衡叮趴,鎖最后才能被釋放,以供其它線程使用

NSConditionLock條件鎖

? ? ? ? 當(dāng)我們?cè)谑褂枚嗑€程的時(shí)候权烧,有時(shí)一把只會(huì)lock和unlock的鎖未必就能完全滿足我們的使用眯亦。因?yàn)槠胀ǖ逆i只能關(guān)心鎖與不鎖咳蔚,而不在乎用什么鑰匙才能開鎖,而我們?cè)谔幚碣Y源共享的時(shí)候搔驼,多數(shù)情況是只有滿足一定條件的情況下才能打開這把鎖:

條件鎖.png

? ? ? ?在線程1中的加鎖使用了lock谈火,所以是不需要條件的,所以順利的就鎖住了舌涨,但在unlock的使用了一個(gè)整型的條件糯耍,它可以開啟其它線程中正在等待這把鑰匙的臨界地,而線程2則需要一把被標(biāo)識(shí)為2的鑰匙囊嘉,所以當(dāng)線程1循環(huán)到最后一次的時(shí)候温技,才最終打開了線程2中的阻塞。但即便如此扭粱,NSConditionLock也跟其它的鎖一樣舵鳞,是需要lock與unlock對(duì)應(yīng)的,只是lock,lockWhenCondition:與unlock琢蛤,unlockWithCondition:是可以隨意組合的蜓堕,當(dāng)然這是與你的需求相關(guān)的。

NSDistributedLock分布式鎖

? ? ? ? 以上所有的鎖都是在解決多線程之間的沖突博其,但如果遇上多個(gè)進(jìn)程或多個(gè)程序之間需要構(gòu)建互斥的情景該怎么辦呢套才?這個(gè)時(shí)候我們就需要使用到NSDistributedLock了,從它的類名就知道這是一個(gè)分布式的Lock慕淡,NSDistributedLock的實(shí)現(xiàn)是通過(guò)文件系統(tǒng)的背伴,所以使用它才可以有效的實(shí)現(xiàn)不同進(jìn)程之間的互斥,但NSDistributedLock并非繼承于NSLock峰髓,它沒(méi)有l(wèi)ock方法傻寂,它只實(shí)現(xiàn)了tryLock,unlock携兵,breakLock疾掰,所以如果需要lock的話,你就必須自己實(shí)現(xiàn)一個(gè)tryLock的輪詢眉孩,下面通過(guò)代碼簡(jiǎn)單的演示一下吧:

分布式鎖

? ? ? 先運(yùn)行程序A,然后立即運(yùn)行程序B,根據(jù)打印你可以清楚的發(fā)現(xiàn)个绍,當(dāng)程序A剛運(yùn)行的時(shí)候勒葱,程序B一直處于等待中浪汪,當(dāng)大概10秒過(guò)后,程序B便打印出了appB:OK的輸出凛虽,以上便實(shí)現(xiàn)了兩上不同程序之間的互斥死遭。/Users/mac/Desktop/earning__是一個(gè)文件或文件夾的地址,如果該文件或文件夾不存在凯旋,那么在tryLock返回YES時(shí)呀潭,會(huì)自動(dòng)創(chuàng)建該文件/文件夾钉迷。在結(jié)束的時(shí)候該文件/文件夾會(huì)被清除,所以在選擇的該路徑的時(shí)候钠署,應(yīng)該選擇一個(gè)不存在的路徑糠聪,以防止誤刪了文件。

? ? ? ? 這是用在多進(jìn)程之間共享資源的鎖谐鼎,對(duì) iOS 來(lái)說(shuō)暫時(shí)沒(méi)用處舰蟆。

參考文獻(xiàn)

1.www.tanhao.me/pieces/616.html/

2.justinyan.me/post/1609

3.www.tanhao.me/pieces/643.html/

4.www.tanhao.me/pieces/1731.html/

5.iOS 鎖

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市狸棍,隨后出現(xiàn)的幾起案子身害,更是在濱河造成了極大的恐慌,老刑警劉巖草戈,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件塌鸯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡唐片,警方通過(guò)查閱死者的電腦和手機(jī)丙猬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)费韭,“玉大人淮悼,你說(shuō)我怎么就攤上這事±克迹” “怎么了袜腥?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)钉汗。 經(jīng)常有香客問(wèn)我羹令,道長(zhǎng),這世上最難降的妖魔是什么损痰? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任福侈,我火速辦了婚禮,結(jié)果婚禮上卢未,老公的妹妹穿的比我還像新娘肪凛。我一直安慰自己,他們只是感情好辽社,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布伟墙。 她就那樣靜靜地躺著,像睡著了一般滴铅。 火紅的嫁衣襯著肌膚如雪戳葵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天汉匙,我揣著相機(jī)與錄音拱烁,去河邊找鬼生蚁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛戏自,可吹牛的內(nèi)容都是我干的邦投。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼擅笔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尼摹!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起剂娄,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蠢涝,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后阅懦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體和二,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年耳胎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惯吕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怕午,死狀恐怖废登,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情郁惜,我是刑警寧澤堡距,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站兆蕉,受9級(jí)特大地震影響羽戒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜虎韵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一易稠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧包蓝,春花似錦驶社、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至绳泉,卻和暖如春逊抡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背零酪。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工冒嫡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人四苇。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓孝凌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親月腋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蟀架,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

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

  • 鎖是一種同步機(jī)制,用于多線程環(huán)境中對(duì)資源訪問(wèn)的限制iOS中常見(jiàn)鎖的性能對(duì)比圖(摘自:ibireme): iOS鎖的...
    LiLS閱讀 1,522評(píng)論 0 6
  • 在平時(shí)的開發(fā)中經(jīng)常使用到多線程榆骚,在使用多線程的過(guò)程中片拍,難免會(huì)遇到資源競(jìng)爭(zhēng)的問(wèn)題,那我們?cè)趺磥?lái)避免出現(xiàn)這種問(wèn)題那妓肢? ...
    IAMCJ閱讀 3,099評(píng)論 2 25
  • 拋磚引玉 說(shuō)到鎖不得不提線程安全捌省,說(shuō)到線程安全,作為iOS程序員又不得不提 nonatomic 與 atomic ...
    Inlight先森閱讀 2,054評(píng)論 0 23
  • 在多線程操作過(guò)程中碉钠,往往一個(gè)數(shù)據(jù)同時(shí)被多個(gè)線程讀寫纲缓,在這種情況下,如果沒(méi)有相應(yīng)的機(jī)制對(duì)數(shù)據(jù)進(jìn)行保護(hù)喊废,就很可能會(huì)發(fā)...
  • 本文不介紹各種鎖的高級(jí)用法祝高,只是整理鎖相關(guān)的知識(shí)點(diǎn),幫助理解污筷。 鎖的作用 防止在多線程(多任務(wù))的情況下對(duì)共享資源...
    HelloiWorld閱讀 2,897評(píng)論 0 8