鎖的類别:互斥鎖,遞歸鎖,條件鎖,自旋鎖等
鎖的實作方式:NSLock,NSRecursiveLock, NSConditionLock,@synchronized,GCD的信号量等
下面說一下常用的幾種鎖:
[email protected]:對象級别所,互斥鎖,性能較差不推薦使用
@synchronized(這裡添加一個OC對象,一般使用self) {
這裡寫要加鎖的代碼
}
@synchronized使用注意點
1.加鎖的代碼盡量少
2.添加的OC對象必須在多個線程中都是同一對象,下面舉一個反例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | |
結果賣票又出錯了,出現這個原因的問題是每個線程都會建立一個object對象,鎖後面加的object在不同線程中就不同了;
把@synchronized(object)改成 @synchronized(self)就能得到了正确結果
2.NSLock:互斥鎖,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
NSLock: 使用注意,不能多次調用 lock方法,會造成死鎖
3.NSRecursiveLock:遞歸鎖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
4.NSConditionLock:條件鎖
NSConditionLock:條件鎖,一個線程獲得了鎖,其它線程等待。
[xxxx lock]; 表示 xxx 期待獲得鎖,如果沒有其他線程獲得鎖(不需要判斷内部的condition) 那它能執行此行以下代碼,如果已經有其他線程獲得鎖(可能是條件鎖,或者無條件鎖),則等待,直至其他線程解鎖
[xxx lockWhenCondition:A條件]; 表示如果沒有其他線程獲得該鎖,但是該鎖内部的condition不等于A條件,它依然不能獲得鎖,仍然等待。如果内部的condition等于A條件,并且沒有其他線程獲得該鎖,則進入代碼區,同時設定它獲得該鎖,其他任何線程都将等待它代碼的完成,直至它解鎖。
[xxx unlockWithCondition:A條件]; 表示釋放鎖,同時把内部的condition設定為A條件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
列印結果:
如果我們把代碼中[_cdtLock lockWhenCondition:2]換成[_cdtLock lockWhenCondition:1]則會發現出現如下結果
和我們預想的在i = 1後面列印thread2不符合,這是因為conditionLockAction1中的代碼段也需要獲得鎖,同時在循環執行過後把condition置成了2,那麼conditionLockAction2就再也沒機會加鎖了,是以不列印thread2。
我們可以靠下面的代碼驗證
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | |
現在的結果就和我們預期的一樣了
5.NSCondition:可以了解為互斥鎖和條件鎖的結合
用生産者消費者中的例子可以很好的了解NSCondition
1.生産者要取得鎖,然後去生産,生産後将生産的商品放入庫房,如果庫房滿了,則wait,就釋放鎖,直到其它線程喚醒它去生産,如果沒有滿,則生産商品後調用signal,可以喚醒在此condition上等待的線程。
2.消費者要取得鎖,然後去消費,如果目前沒有商品,則wait,釋放鎖,直到有線程去喚醒它消費,如果有商品,則消費後會通知正在等待的生産者去生産商品。
生産者和消費者的關鍵是:當庫房已滿時,生産者等待,不再繼續生産商品,當庫房已空時,消費者等待,不再繼續消費商品,走到庫房有商品時,會由生産者通知消費來消費。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | |
了解死鎖
概念:死鎖是指兩個或兩個以上的程序(線程)在執行過程中,由于競争資源或者由于彼此通信而造成的一種阻塞的現象,若無外力作用,它們都将無法推進下去。
産生死鎖的4個必要條件
1)互斥條件:指程序對所配置設定到的資源進行排它性使用,即在一段時間内某資源隻由一個程序占用。如果此時還有其它程序請求資源,則請求者隻能等待,直至占有資源的程序用畢釋放。
2)請求和保持條件:指程序已經保持至少一個資源,但又提出了新的資源請求,而該資源已被其它程序占有,此時請求程序阻塞,但又對自己已獲得的其它資源保持不放。
3)不剝奪條件:指程序已獲得的資源,在未使用完之前,不能被剝奪,隻能在使用完時由自己釋放。
4)環路等待條件:指在發生死鎖時,必然存在一個程序——資源的環形鍊,即程序集合{P0,P1,P2,···,Pn}中的P0正在等待一個P1占用的資源;P1正在等待P2占用的資源,……,Pn正在等待已被P0占用的資源。