iOS 多線程併發-鎖

這個應該是全平臺都會遇到的問題了。當某個對象會被多個線程修改的時候,有可能一個線程訪問這個對象的時候另外一個線程已經把它刪掉了,致使 Crash。比較常見的是在網絡任務隊列裏面,主線程往隊列裏面加入任務,網絡線程同時進行刪除操做致使掛掉。html

例子

這個真要寫比較完整的併發操做的例子就有點複雜了。shell

解決方法

    • 加鎖
      • NSLock

        普通的鎖,加鎖的時候 lock,解鎖調用 unlock。網絡

        - (void)addPlayer:(Player *)player {
           if (player == nil) return;
                NSLock* aLock = [[NSLock alloc] init];
                [aLock lock];
        
                [players addObject:player];
        
                [aLock unlock];
           }
        }

        能夠使用標記符 @synchronized 簡化代碼:多線程

        - (void)addPlayer:(Player *)player {
           if (player == nil) return;
           @synchronized(players) {
              [players addObject:player];
           }
        }
      • NSRecursiveLock 遞歸鎖

        使用普通的 NSLock 若是在遞歸的狀況下或者重複加鎖的狀況下,本身跟本身搶資源致使死鎖。Cocoa 提供了 NSRecursiveLock 鎖能夠屢次加鎖而不會死鎖,只要 unlock 次數跟 lock 次數同樣就好了。併發

      • NSConditionLock 條件鎖

        多數狀況下鎖是不須要關心什麼條件下 unlock 的,要用的時候鎖上,用完了就 unlock 就完了。Cocoa 提供這種條件鎖,能夠在知足某種條件下才解鎖。這個鎖的 lock 和 unlock, lockWhenCondition 是隨意組合的,能夠不用對應起來。分佈式

      • NSDistributedLock 分佈式鎖

        這是用在多進程之間共享資源的鎖,對 iOS 來講暫時沒用處。線程

    • 無鎖
      放棄加鎖,採用原子操做,編寫無鎖隊列解決多線程同步的問題。酷殼有篇介紹無鎖隊列的文章能夠參考一下:無鎖隊列的實現code

    • 使用其餘備選方案代替多線程:Operation Objects, GCD, Idle-time notifications, Asynchronous functions, Timers, Separate processes。
相關文章
相關標籤/搜索