例1
- (void)viewDidLoad{
[super viewDidLoad];
NSLog(@"1");
dispatch_sync(dispatch_get_main_queue(),^{
NSLog(@"2");
});
NSLog(@"3");
}
此例死锁。viewDidLoad 和 block 的任务都要在主线程上运行,主线程是串行队列,不能够并发,属于临界资源。block 是同步任务,在block没有执行结束时 dispatch_sync 不会返回,即不能够往下执行。如此,viewDidLoad 占有主线程并等待 block 执行,block 等待获取主线程而阻塞,死锁形成。
例2
- (void)viewDidLoad{
[super viewDidLoad];
NSLog(@"1");
dispatch_async(dispatch_get_main_queue(),^{
NSLog(@"2");
});
NSLog(@"3");
}
此例不会死锁。block 是异步任务,会立即返回,即不管 block 怎样,都会回到 viewDidLoad 继续执行。因为主线程是串行队列,所以 block 一开始会被阻塞而去等待获取主线程。与例1不同的是,block 在 viewDidLoad 任务完成后得到了主线程,所以没有死锁。
例3
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
NSLog(@"1");
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
NSLog(@"2");
});
NSLog(@"3");
});
此例不会死锁。globe queue 是并行队列,其中的任务可以并发执行,不属于临界资源