1、基本术语
同步、异步、并发、串行
- 同步和异步的影响:能否开启新线程
- 同步:在当前线程中执行任务,不具备开启新线程的能力
- 异步:在新的线程中执行任务,具备开启新线程的能力
- 并发和串行主要影响:任务的执行方式
- 并发:多个任务并发(同时)执行
- 串行:一个任务执行完毕后,再执行下一个任务
并发队列 | 串行队列 | 主队列 | |
同步 | 没有开启新线程 串行执行任务 | 没有开启新线程 串行执行任务 | 没有开启新线程 串行执行任务 |
异步 | 有开启新线程 并发执行任务 | 有开启新线程 串行执行任务 | 没有开启新线程 串行执行任务 |
- 使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)
- 下面代码段,产生死锁
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"1");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
NSLog(@"2");
});
NSLog(@"3");
}
- 下面代码块,不会产生死锁
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"1");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"2");
});
NSLog(@"3");
}
执行结果:
2022-01-25 15:16:29.393419+0800 gcd[23885:2805070] 1
2022-01-25 15:16:29.393539+0800 gcd[23885:2805070] 3
2022-01-25 15:16:29.404251+0800 gcd[23885:2805070] 2
- 下面代码,会死锁
- (void)viewDidLoad {
[super viewDidLoad];
[self test2];
}
- (void)test2 {
NSLog(@"1");
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)
会在执行任务3的时候产生死锁!
- 下面代码块,不会死锁,因为不是当前队列里面
- (void)viewDidLoad {
[super viewDidLoad];
[self test3];
}
- (void)test3 {
NSLog(@"1");
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue2 = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue2, ^{ // 在另外一个队列里面,不会在当前队列里面阻塞,所以不会死锁
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
打印结果:
2022-01-25 15:46:45.171460+0800 gcd[25030:2823720] 1
2022-01-25 15:46:45.171592+0800 gcd[25030:2823720] 5
2022-01-25 15:46:45.171602+0800 gcd[25030:2823778] 2
2022-01-25 15:46:45.171690+0800 gcd[25030:2823778] 3
2022-01-25 15:46:45.171761+0800 gcd[25030:2823778] 4
- 下面代码块,也不会产生死锁
- (void)viewDidLoad {
[super viewDidLoad];
[self test3];
}
- (void)test3 {
NSLog(@"1");
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue2 = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue2, ^{ // 在另外一个队列里面,不会在当前队列里面阻塞,所以不会死锁
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
- 下面代码块,也不会产生死锁,因为是并发队列,可以同时执行多个任务,不会阻塞
- (void)viewDidLoad {
[super viewDidLoad];
[self test3];
}
- (void)test3 {
NSLog(@"1");
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{ //
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}