顧名思義弓候,就是對(duì)一個(gè)線程加個(gè)鎖??郎哭。具體怎么辦,看代碼菇存。
用起來很簡(jiǎn)單夸研。
bbbbb.gif
如果對(duì)一個(gè)數(shù)據(jù)在多個(gè)線程中都有對(duì)它的操作,可能會(huì)造成意向不到的結(jié)果亥至。
如下代碼抬闯,我在兩個(gè)線程對(duì)同一個(gè)數(shù)組進(jìn)行刪除元素溶握。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.dataArr = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", nil];
dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(quene, ^{
for (int i = 0; i < 8; i++) {
[self deleteObj];
}
});
dispatch_async(quene, ^{
for (int i = 0; i < 8; i++) {
[self deleteObj];
}
});
}
- (void)deleteObj {
if (self.dataArr.count > 0) {
NSString *obj = [self.dataArr lastObject];
NSLog(@"666_SunDePrint_999:刪除了%@", obj);
[self.dataArr removeLastObject];
}else{
NSLog(@"666_SunDePrint_999:%@", @"已經(jīng)刪除完了");
}
}
結(jié)果:
沒加線程鎖的結(jié)果.png
很明顯看到萍肆,第6個(gè)元素竟然刪除了2遍U陀臁!感覺這是不應(yīng)該發(fā)生的亲铡,但是它確實(shí)發(fā)生了葡兑。怎么辦吆鹤?當(dāng)然是加線程鎖了疑务。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//初始化一個(gè)NSLock
self.lock = [[NSLock alloc] init];
self.dataArr = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", nil];
dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(quene, ^{
for (int i = 0; i < 8; i++) {
[self deleteObj];
}
});
dispatch_async(quene, ^{
for (int i = 0; i < 8; i++) {
[self deleteObj];
}
});
}
- (void)deleteObj {
[self.lock lock];
if (self.dataArr.count > 0) {
NSString *obj = [self.dataArr lastObject];
NSLog(@"666_SunDePrint_999:刪除了%@", obj);
[self.dataArr removeLastObject];
}else{
NSLog(@"666_SunDePrint_999:%@", @"已經(jīng)刪除完了");
}
[self.lock unlock];
}
通過一個(gè)NSLock,在對(duì)數(shù)組操作前先加把鎖婴削,不讓別的線程訪問廊镜,操作完后就unlock解鎖。
加完鎖??的結(jié)果.png
二衡楞、@synchronized
除了NSLock當(dāng)做線程鎖,@synchronized也可以迷守。通過保護(hù)一個(gè)對(duì)象,一般是self茵瘾,就保護(hù)了這個(gè)對(duì)象的數(shù)據(jù)祈惶。
- (void)deleteObj {
@synchronized(self){
if (self.dataArr.count > 0) {
NSString *obj = [self.dataArr lastObject];
NSLog(@"666_SunDePrint_999:刪除了%@", obj);
[self.dataArr removeLastObject];
}else{
NSLog(@"666_SunDePrint_999:%@", @"已經(jīng)刪除完了");
}
}
}
效果和NSLock一樣。