顧名思義,就是對一個線程加個鎖??。具體怎么辦,看代碼。
用起來很簡單。
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一樣。