iOS三种线程锁
2019-06-18 本文已影响0人
宋魁鹏
1.使用NSLock实现的锁
NSLock是Cocoa提供给我们最基本的锁对象,这也是我们经常所使用的,除lock和unlock方法外,NSLock还提供了tryLock和lockBeforeDate:两个方法,前一个方法会尝试加锁,如果锁不可用(已经被锁住),刚并不会阻塞线程,并返回NO。lockBeforeDate:方法会在所指定Date之前尝试加锁,如果在指定时间之前都不能加锁,则返回NO。
//NSLock锁
NSLock *lock = [[NSLock alloc] init];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[lock lock];
NSLog(@"线程1开始");
sleep(10);
NSLog(@"线程1结束");
[lock unlock];
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(2);//以保证让线程2的代码后执行
[lock lock];
NSLog(@"线程2");
[lock unlock];
});
打印结果
2019-06-18 11:49:36.404882+0800 AAAAA[2249:112124] 线程1开始
2019-06-18 11:49:46.409998+0800 AAAAA[2249:112124] 线程1结束
2019-06-18 11:49:46.410351+0800 AAAAA[2249:112125] 线程2
2.使用synchronized关键字构建的锁
@synchronized指令实现锁的优点就是我们不需要在代码中显式的创建锁对象,便可以实现锁的机制,但作为一种预防措施,@synchronized块会隐式的添加一个异常处理例程来保护代码,该处理例程会在异常抛出的时候自动的释放互斥锁。所以如果不想让隐式的异常处理例程带来额外的开销,你可以考虑使用锁对象。
UIView *other = [[UIView alloc] init];
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(self){
NSLog(@"线程1开始");
sleep(10);
NSLog(@"线程1结束");
}
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
@synchronized(other){
NSLog(@"线程2");
}
});
//线程3
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(2);
@synchronized(self){
NSLog(@"线程3");
}
});
打印结果
2019-06-18 11:57:22.831604+0800 AAAAA[2363:119063] 线程1开始
2019-06-18 11:57:23.834307+0800 AAAAA[2363:119066] 线程2
2019-06-18 11:57:32.835082+0800 AAAAA[2363:119063] 线程1结束
2019-06-18 11:57:32.835410+0800 AAAAA[2363:119070] 线程3
3.使用GCD中“信号量”来实现的”锁”
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
//线程1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"线程1开始");
sleep(10);
NSLog(@"线程1结束");
dispatch_semaphore_signal(semaphore);
});
//线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(1);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"线程2");
dispatch_semaphore_signal(semaphore);
});
打印结果
2019-06-18 12:02:14.863220+0800 AAAAA[2439:123901] 线程1开始
2019-06-18 12:02:24.868817+0800 AAAAA[2439:123901] 线程1结束
2019-06-18 12:02:24.869162+0800 AAAAA[2439:123900] 线程2