iOS中有哪些技術(shù)可以保證線程安全?
1塊資源可能會(huì)被多個(gè)線程共享甚纲,也就是多個(gè)線程可能會(huì)訪問(wèn)同一塊資源口锭,比如多個(gè)線程訪問(wèn)同一個(gè)對(duì)象、同一個(gè)變量介杆、同一個(gè)文件鹃操。當(dāng)多個(gè)線程訪問(wèn)同一塊資源時(shí)况既,很容易引發(fā)數(shù)據(jù)錯(cuò)亂和數(shù)據(jù)安全問(wèn)題。此時(shí)组民,我們需要用線程鎖來(lái)解決。
線程數(shù)據(jù)安全的方法:
1悲靴、nonatomic atomic:使用atomic多線程原子性控制臭胜,atomic的原理給setter加上鎖,getter不會(huì)加鎖癞尚。OC在定義屬性時(shí)有nonatomic和atomic兩種選擇
atomic:原子屬性耸三,為setter方法加鎖(默認(rèn)就是atomic)
nonatomic:非原子屬性,不會(huì)為setter方法加鎖
#import "YYViewController.h"
@interface YYViewController ()
//剩余票數(shù)
@property(nonatomic,assign) int leftTicketsCount;
@property(nonatomic,strong)NSThread *thread1;
@property(nonatomic,strong)NSThread *thread2;
@property(nonatomic,strong)NSThread *thread3;
@end
@implementation YYViewController
- (void)viewDidLoad28
{
[super viewDidLoad];
//默認(rèn)有10張票
self.leftTicketsCount=10;
//開(kāi)啟多個(gè)線程浇揩,模擬售票員售票
self.thread1=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];
self.thread1.name=@"售票員A";
self.thread2=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];
self.thread2.name=@"售票員B";
self.thread3=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];
self.thread3.name=@"售票員C";
[self.thread1 start];
[self.thread2 start];
[self.thread3 start];
}
-(void)sellTickets
{
while (true)
{
if (self.leftTicketsCount > 0 )
{
[NSThread sleepForTimeInterval:0.5];
self.leftTicketsCount--;
NSLog(@"thread:%@ ---> %ld",[[NSThread currentThread] name],self.leftTicketsCount);
}
else
{
break;
}
}
}
2仪壮、使用GCD實(shí)現(xiàn)atomic操作:給某字段的setter和getter方法加上同步隊(duì)列:
- (void)setCount:(NSInteger)newcount
{
dispatch_sync(_synQueue, ^{
count = newcount;
});
}
- (NSInteger)count
{
__block NSInteger localCount;
dispatch_sync(_synQueue, ^{
localCount = count;
});
return localCount;
}
3、 使用NSLock
- (void)threadRunLock
{
_lock = [[NSLock alloc]init];
while (true)
{
[_lock lock];
if (self.number > 0 )
{
[NSThread sleepForTimeInterval:0.5];
self.number --;
NSLog(@"thread:%@ ---> %ld",[[NSThread currentThread] name],self.number);
}
[_lock unlock];
}
}
相當(dāng)于給代碼片段加上lock了胳徽,所以依次輸出9-0
4积锅、使用互斥鎖
使用格式
@synchronized(鎖對(duì)象) { // 需要鎖定的代碼 }
注意:鎖定1份代碼只用1把鎖,用多把鎖是無(wú)效的
-(void)sellTickets
{
while (true)
{
@synchronized(self)
{
//只能加一把鎖
//1.先檢查票數(shù)
int count=self.leftTicketsCount;
if (count>0)
{
//暫停一段時(shí)間
[NSThread sleepForTimeInterval:0.002];
//2.票數(shù)-1
self.leftTicketsCount= count-1;
//獲取當(dāng)前線程
NSThread *current=[NSThread currentThread];
NSLog(@"%@--賣(mài)了一張票养盗,還剩余%d張票",current,self.leftTicketsCount);
}
else
{
//退出線程
[NSThread exit];
}
}
}
}
互斥鎖的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):能有效防止因多線程搶奪資源造成的數(shù)據(jù)安全問(wèn)題
缺點(diǎn):需要消耗大量的CPU資源
互斥鎖的使用前提:
多條線程搶奪同一塊資源
相關(guān)專(zhuān)業(yè)術(shù)語(yǔ):
線程同步,多條線程按順序地執(zhí)行任務(wù)缚陷。互斥鎖往核,就是使用了線程同步技術(shù)
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者