一、多線程環(huán)境下的安全問(wèn)題
由于一個(gè)資源可以被多個(gè)線程同時(shí)訪問(wèn)查邢,這樣有可能會(huì)導(dǎo)致數(shù)據(jù)混亂蔗崎,引發(fā)數(shù)據(jù)的安全問(wèn)題,所以說(shuō)在多線程環(huán)境下扰藕,原子操作是必要的缓苛。
-
本文中介紹一下自旋鎖和互斥鎖。
- 自旋鎖:當(dāng)給實(shí)例變量的@property設(shè)置atomic屬性的時(shí)候邓深,會(huì)給這個(gè)變量加一個(gè)自旋鎖未桥。
- 互斥鎖:通過(guò)@synchronized來(lái)創(chuàng)建一個(gè)互斥鎖。多線程環(huán)境下芥备,如果訪問(wèn)同一個(gè)資源冬耿,那么必須使用同一把鎖才能鎖住。
比如說(shuō):去銀行自助取款機(jī)取錢(qián)萌壳,如果另外一個(gè)地方有個(gè)人也在使用你的銀行卡號(hào)進(jìn)行存錢(qián)亦镶,那么此時(shí)就使用atomic和nonatomic中的哪個(gè)呢日月?很明顯,選擇atomic缤骨,因?yàn)橥瑫r(shí)進(jìn)行兩個(gè)操作爱咬,對(duì)于同一個(gè)賬號(hào),很可能會(huì)造成數(shù)據(jù)的混亂绊起,所以必須要進(jìn)行加鎖精拟,限制用戶的訪問(wèn)。
二勒庄、自旋鎖
- OC在定義屬性的時(shí)候有atomic和nonatomic兩種方式
- atomic:原子屬性串前,線程安全,需要消耗大量的資源实蔽,只會(huì)給setter方法加鎖荡碾,不會(huì)給getter方法加鎖
- nonatomic:非原子屬性,非線程安全局装,不會(huì)給setter方法加鎖坛吁,在像iPhone這種內(nèi)存較小的移動(dòng)設(shè)備上,如果沒(méi)有多線程間的通信铐尚,那么nonatomic就是一個(gè)非常好的選擇拨脉。
- 一般情況下,我們都只需要在主線程中進(jìn)行操作的宣增,所以是不需要加鎖的玫膀。
- 應(yīng)用場(chǎng)景:
比較適合做一些不耗時(shí)的操作
三、互斥鎖
- 在多線程開(kāi)發(fā)中爹脾,我們采用@synchronized來(lái)創(chuàng)建一個(gè)互斥鎖帖旨,保證在同一時(shí)刻只有一個(gè)線程對(duì)其進(jìn)行操作。
- 開(kāi)發(fā)中如果需要加鎖灵妨,只用使用self就行了解阅。
@synchronized(self){
NSInteger currentNum = self.totalNum;
if (currentNum > 0) {
self.totalNum = currentNum - 1;
NSLog(@"%@賣(mài)了一張票,還剩下%zd張票",[NSThread currentThread].name,self.totalNum);
} else {
return;
}
}
四、互斥鎖和自旋鎖的比較
- 共同點(diǎn):多線程環(huán)境下泌霍,都可以保證在同一時(shí)刻只有一個(gè)線程在使用被鎖住的代碼塊货抄。
- 區(qū)別:自旋鎖對(duì)比互斥鎖,它不會(huì)在等待上一個(gè)線程執(zhí)行任務(wù)結(jié)束之前進(jìn)入睡眠狀態(tài)朱转,直至上一個(gè)任務(wù)執(zhí)行完畢蟹地,再進(jìn)行喚醒和執(zhí)行任務(wù)。因此藤为,互斥鎖會(huì)比自旋鎖鎖住的代碼執(zhí)行的時(shí)間長(zhǎng)锈津。
- 舉例說(shuō)明:兩個(gè)人去上廁所,一個(gè)人比較急凉蜂,一個(gè)人不急,比較急的相當(dāng)于是訪問(wèn)自旋鎖鎖住的代碼的那個(gè)對(duì)象,而不急的那個(gè)人是訪問(wèn)互斥鎖鎖住的代碼的那個(gè)對(duì)象窿吩。