顾名思义,就是对一个线程加个锁🔐。具体怎么办,看代码。
用起来很简单。
bbbbb.gif
如果对一个数据在多个线程中都有对它的操作,可能会造成意向不到的结果。
如下代码,我在两个线程对同一个数组进行删除元素。
- (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:%@", @"已经删除完了");
}
}
结果:
没加线程锁的结果.png
很明显看到,第6个元素竟然删除了2遍!!感觉这是不应该发生的,但是它确实发生了。怎么办?当然是加线程锁了。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//初始化一个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:%@", @"已经删除完了");
}
[self.lock unlock];
}
通过一个NSLock,在对数组操作前先加把锁,不让别的线程访问,操作完后就unlock解锁。
加完锁🔐的结果.png二、@synchronized
除了NSLock当做线程锁,@synchronized也可以。通过保护一个对象,一般是self,就保护了这个对象的数据。
- (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:%@", @"已经删除完了");
}
}
}
效果和NSLock一样。
网友评论