iOS 幾種常用鎖介紹
阿新 • • 發佈:2021-10-06
https://www.jianshu.com/p/57667e2217a5
https://blog.csdn.net/liupinghui/article/details/67637830
- NSLock
- NSLock是Cocoa提供給我們最基本的鎖物件,這也是我們經常使用的,除lock和unlock外,NSLock還提供了tryLock和lockBeforeDate:兩個方法,前一個方法會嘗試加鎖,如果鎖不可用(已經被鎖住),並不會阻塞執行緒,直接返回NO。後一個方法則會在指定的Date之前嘗試加鎖,如果在指定的時間內都不能加鎖,則返回NO
- synchronized(互斥鎖)
- synchronized會建立一個異常捕獲handler和一些內部的鎖,所以使用@synchronized替換普通鎖的代價是要付出更多的時間消耗
- 建立給給@synchronized指令的物件是一個用來區別保護塊的唯一識別符號。如果你在兩個不同的執行緒裡面執行上述方法,每次在一個執行緒傳遞了一個不同的物件給anObj引數,那麼每次都將會擁有它的鎖,並持續處理,中間不會被其他執行緒阻塞。然而如果你傳遞的是同一個物件,那麼多個執行緒中的一個執行緒會首先獲得該鎖,而其他執行緒將會被阻塞,直到第一個執行緒完成它的臨界區
- 作為一個預防措施。@synchronized塊隱式的新增一個異常處理例程來保護程式碼,該處理例程會在異常丟擲的時候自動的釋放互斥鎖,這就意味著為了使用@synchronized指令,你必須在你的程式碼中啟用異常處理。如果你不想讓隱式的異常處理例程帶來額外的開銷,那麼可以使用其他的鎖
- atomic
- atomic只是給成員變數的set和get方法加了一個鎖,防止多執行緒一直去讀寫這個成員變數。但這也僅僅是對讀寫的鎖定,並不是執行緒安全。而且使用atomic比nonatomic慢了將近20倍
- OSSpinlock
- 自旋鎖
- 耗時最少
- 自旋鎖幾乎不進入核心,僅僅是重新載入自旋鎖
- 如果自旋鎖被佔用時間在一百納秒以內,效能還是比較高的,因為減少了代價較高的系統呼叫和一系列的上下文切換
- 但是該鎖不是萬能的,如果該鎖佔用的時間比較多的時候,使用該鎖會導致佔用的cpu較多
- pthread_mutex
- 是底層的API,在各種加鎖方式中屬於效能比較高的
- 如果自旋鎖佔用的時間比較多,那麼使用pthread是一個不錯的選擇
- NSConditionLock(條件鎖)
- 條件鎖與特定的使用者定義的條件有關,它可以確保一個執行緒可以獲取滿足一定條件的鎖
- 內部涉及到訊號量機制,一旦一個執行緒獲取鎖以後,它可以放棄鎖並設定相關條件,這時候其他執行緒競爭該鎖
- 執行緒之間的競爭激烈,涉及到條件鎖檢測、執行緒間通訊,系統呼叫、下文切換比較頻繁
- NSRecursiveLock遞迴鎖
- NSRecursiveLock實際上定義的是一個遞迴鎖,這個鎖可以被同一執行緒多次請求,而不會引起死鎖。這主要是用在迴圈或者遞迴操作中
- 總結:
- 如果只是粗略的使用鎖,不考慮效能可以使用synchronized
- 如果對效率有較高的要求,採用OSSpinLock
- 因為pthread的鎖也是使用OSSpinLock實現的,而且在OSSpinLock的實現過程中,並沒有進入系統kernel,使用OSSpinLock可以節省系統呼叫和上下文切換
- NSLock/NSConditionLock/NSRecursiveLock耗時接近。220ms左右
- dispatch_barrier_async的效能並沒有我們想象中的那樣好,這與執行緒同步排程開銷有關
作者:深度碼農患者
連結:https://www.jianshu.com/p/57667e2217a5
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。