iOS多线程篇-GCD理解一
2019-08-16 本文已影响0人
亲爱的大倩倩
执行原则
- 同步dispatch_sync
阻塞线程,必须等待当前语句执行完毕,才会执行下一条语句 - 异步dispatch_async
不阻塞线程,不用等待当前语句执行完毕,就会执行下一条语句 -
串行队列上两个同步任务循环等待 = 死锁:会直接崩溃
串行队列同步任务
- (void)viewDidLoad {
dispatch_sync(serialQueue, ^{
[self doSomething];
});
}
viewDidLoad方法在主队列中,是任务1
block被提交到自定义的串行队列中,是任务2
串行队列是先进先出
viewDidLoad在主队列,默认是在主线程执行的
block因为是被同步提交的,意味着在当前线程执行,所以也是被送到主线程中去执行
因为不是在同一个队列,不会被锁住,可以正常执行
死锁: 会直接崩溃
两个任务被同步分配到同一个串行队列上循环等待,就会死锁
注意不局限于主队列,其他队列也会引起
主队列死锁
- (void)viewDidLoad {
dispatch_sync(dispatch_get_main_queue(), ^{
[self doSomething];
});
}
viewDidLoad方法就是任务1
接下来的block块是任务2,会堵塞线程
必须等block执行完毕才能执行下一个
doSomething方法时任务3
任务1必须等任务2完成才能结束
但任务2又得等任务3执行完毕才能出来执行
任务3又无法执行
就死锁咯~
自定义的串行队列死锁
当执行到sync时,相当于竖起一个栅栏堵塞住当前队列,意味着必须将block块执行完毕才能执行下面的4,但block里面的任务3排在4后面
执行完block任务则必须执行完任务3
但任务3排在任务4后面
任务4又排在block块后面
所以就死锁了
代码测试原则
- (void)viewDidLoad {
NSLog(@"1");
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"2");
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
输出12345
- (void)viewDidLoad {
NSLog(@"1");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"2");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
输出15243
- (void)viewDidLoad {
NSLog(@"1");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"2");
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
输出15234
- (void)viewDidLoad {
NSLog(@"1");
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"2");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
输出12435