iOS開發(fā)線程鎖

前言

多線程是現(xiàn)在每個(gè)開發(fā)必定知道的。這哥們(多線程)是用來干啥的?舉個(gè)例子拿單線程來說,單線程就是你寫的代碼一步一步執(zhí)行,完全按照順序執(zhí)行,科技一步一步進(jìn)步,現(xiàn)在CPU核心數(shù)越來越多,多線程也就成為了現(xiàn)在每個(gè)程序員必回的一個(gè)知識(shí)點(diǎn)。但是使用多線程優(yōu)點(diǎn)就不多說了。要說都是優(yōu)點(diǎn)沒缺點(diǎn),這純瞎說,他的弊端就是資源搶占問題,開辟多條線程占用一定的資源(主線程一般1MB ,其他線程512kb,一般建議同時(shí)最多開三條線程比較合理)。關(guān)于資源搶占問題下面就舉個(gè)例子:在使用多線程的時(shí)候多個(gè)線程可能會(huì)訪問同一塊資源,這樣就很容易引發(fā)數(shù)據(jù)錯(cuò)亂和數(shù)據(jù)安全等問題。解決資源爭(zhēng)用,最直接的想法是引入鎖,對(duì)并發(fā)讀寫的數(shù)據(jù)進(jìn)行保護(hù),保證每次只有一個(gè)線程訪問這一塊資源。
??鎖是最常用的同步工具:一塊公共資源在同一個(gè)時(shí)間只能允許被一個(gè)線程訪問,比如一個(gè)線程A進(jìn)入加鎖資源之后,由于已經(jīng)加鎖,另一個(gè)線程B就無法訪問,只有等待前一個(gè)線程A執(zhí)行完后解鎖,B線程才能訪問加鎖資源。

為什么需要鎖?
?以常見的火車站賣票為例,假設(shè)有20張票,有兩個(gè)窗口同時(shí)售票:

- (void)ticketTest{
    self.ticketsCount = 20;
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    // 線程1
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
                [self sellingTickets];//多線程售票
            }
    });
    // 線程2
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
                [self sellingTickets];//多線程售票
            }
    });
}

- (void)sellingTickets{
    NSInteger oldMoney = self.ticketsCount;
    sleep(0.2);
    oldMoney -= 1;
    self.ticketsCount = oldMoney;
    NSLog(@"當(dāng)前剩余票數(shù)-> %ld", oldMoney);
}

不加鎖

2019-02-21 17:10:40.861358+0800 多線程測(cè)試[8167:20874670] 當(dāng)前剩余票數(shù)-> 19
2019-02-21 17:10:40.861358+0800 多線程測(cè)試[8167:20874671] 當(dāng)前剩余票數(shù)-> 19
2019-02-21 17:10:40.861723+0800 多線程測(cè)試[8167:20874671] 當(dāng)前剩余票數(shù)-> 18
2019-02-21 17:10:40.861723+0800 多線程測(cè)試[8167:20874670] 當(dāng)前剩余票數(shù)-> 18
2019-02-21 17:10:40.861851+0800 多線程測(cè)試[8167:20874670] 當(dāng)前剩余票數(shù)-> 17
2019-02-21 17:10:40.861961+0800 多線程測(cè)試[8167:20874670] 當(dāng)前剩余票數(shù)-> 16
2019-02-21 17:10:40.861989+0800 多線程測(cè)試[8167:20874671] 當(dāng)前剩余票數(shù)-> 16
2019-02-21 17:10:40.862066+0800 多線程測(cè)試[8167:20874670] 當(dāng)前剩余票數(shù)-> 15
2019-02-21 17:10:40.862222+0800 多線程測(cè)試[8167:20874670] 當(dāng)前剩余票數(shù)-> 14
2019-02-21 17:10:40.863234+0800 多線程測(cè)試[8167:20874671] 當(dāng)前剩余票數(shù)-> 13
2019-02-21 17:10:40.863958+0800 多線程測(cè)試[8167:20874670] 當(dāng)前剩余票數(shù)-> 12
2019-02-21 17:10:40.864225+0800 多線程測(cè)試[8167:20874671] 當(dāng)前剩余票數(shù)-> 11
2019-02-21 17:10:40.864529+0800 多線程測(cè)試[8167:20874670] 當(dāng)前剩余票數(shù)-> 10
2019-02-21 17:10:40.865159+0800 多線程測(cè)試[8167:20874671] 當(dāng)前剩余票數(shù)-> 9
2019-02-21 17:10:40.865498+0800 多線程測(cè)試[8167:20874670] 當(dāng)前剩余票數(shù)-> 8
2019-02-21 17:10:40.865777+0800 多線程測(cè)試[8167:20874671] 當(dāng)前剩余票數(shù)-> 7
2019-02-21 17:10:40.866747+0800 多線程測(cè)試[8167:20874670] 當(dāng)前剩余票數(shù)-> 6
2019-02-21 17:10:40.866970+0800 多線程測(cè)試[8167:20874671] 當(dāng)前剩余票數(shù)-> 5
2019-02-21 17:10:40.867402+0800 多線程測(cè)試[8167:20874671] 當(dāng)前剩余票數(shù)-> 4
2019-02-21 17:10:40.867879+0800 多線程測(cè)試[8167:20874671] 當(dāng)前剩余票數(shù)-> 3

不加鎖時(shí)很明顯數(shù)據(jù)發(fā)生了混亂。

iOS中都有哪些鎖?

敲黑板,講重點(diǎn)。
從大的方向講有兩種鎖:

互斥鎖

自旋鎖。

這兩種類型下分別有自己對(duì)應(yīng)的鎖:
NSLock.png

互斥鎖和自旋鎖的對(duì)比:

這兩種鎖的相同點(diǎn)不必多說,都可以避免多線程訪問同一個(gè)值發(fā)生混亂,重點(diǎn)說一下兩種的不同點(diǎn):

互斥鎖:如果共享數(shù)據(jù)已經(jīng)有其他線程加鎖了,線程會(huì)進(jìn)入休眠狀態(tài)等待鎖。一旦被訪問的資源被解鎖, 則等待資源的線程會(huì)被喚醒

自旋鎖:如果共享數(shù)據(jù)已經(jīng)有其他線程加鎖了,線程會(huì)以死循環(huán)的方式等待鎖,一旦被訪問的資源被解鎖, 則等待資源的線程會(huì)立即執(zhí)行

自旋鎖的特點(diǎn):

自旋鎖的性能高于互斥鎖,因?yàn)轫憫?yīng)速度快
自旋鎖雖然會(huì)一直自旋等待獲取鎖,但不會(huì)一直占用CPU,超過了操作系統(tǒng)分配的時(shí)間片會(huì)被強(qiáng)制掛起
自旋鎖如果不能保證所有線程都是同一優(yōu)先級(jí),則可能造成死鎖。

因?yàn)橐陨系奶攸c(diǎn),自旋鎖和互斥鎖也有不同的使用場(chǎng)景:

多核處理器情況下: 如果預(yù)計(jì)線程等待鎖的時(shí)間比較短,短到比線程兩次切換上下文的時(shí)間還要少的情況下,自旋鎖是更好的選擇。
如果時(shí)間比較長,則互斥鎖是比較好的選擇。 單核處理器情況下: 不建議使用自旋鎖。

從詳細(xì)來分鎖:

  • @synchronized

  • NSLock 對(duì)象鎖

  • NSRecursiveLock遞歸鎖

  • NSConditionLock 條件鎖

  • pthread_mutex 互斥鎖(C語言)

  • dispatch_semaphore 信號(hào)量實(shí)現(xiàn)加鎖(GCD)

  • OSSpinLock 自旋鎖

具體使用請(qǐng)移步google。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 ??在使用多線程的時(shí)候多個(gè)線程可能會(huì)訪問同一塊資源,這樣就很容易引發(fā)數(shù)據(jù)錯(cuò)亂和數(shù)據(jù)安全等問題。解決資源爭(zhēng)用,...
    小盟城主閱讀 1,478評(píng)論 0 3
  • 前言 iOS開發(fā)中由于各種第三方庫的高度封裝,對(duì)鎖的使用很少,剛好之前面試中被問到的關(guān)于并發(fā)編程鎖的問題,都是一知...
    喵渣渣閱讀 3,878評(píng)論 0 33
  • 多線程三個(gè)特征:原子性、可見性以及有序性. 同步鎖 /并發(fā)鎖/ 讀寫鎖,顯示鎖, ReentrantLock與Co...
    架構(gòu)師springboot閱讀 2,069評(píng)論 0 5
  • ps: 這篇文章看資料時(shí)頭疼,寫起來時(shí)更頭疼,寫完了說實(shí)話也沒多大用,充其量也就是多了解了一些鎖的內(nèi)容,也許扣字眼...
    前行的烏龜閱讀 1,635評(píng)論 0 5
  • 不經(jīng)意間,就近了元宵節(jié)。 乍暖還寒的天氣是最讓人又愛又恨的,東風(fēng)凌凌,閱海湖的冰面嘎吱作響,湖邊的鐵硬的泥土開始軟...
    決哥不是倔哥閱讀 261評(píng)論 0 3

友情鏈接更多精彩內(nèi)容