-
前言
- 多线程代码执行先后的是怎样的呢?我认为执行代码的先后顺序最外层的dispatch_sync(同步)和dispatch_async(异步)。究竟是不是这样呢?就让我来做以下验证吧。
1、同步(串行/并行)队列
- (void)viewDidLoad {
[super viewDidLoad];
[self test];
}
/** 输出
* DISPATCH_QUEUE_CONCURRENT : 1 2 3 4 13 14 7 8 5 6
* DISPATCH_QUEUE_SERIAL: 1 2 3 4 13 14 7 8 5 6
*/
- (void)test{
NSLog(@"ming -- 1");
NSLog(@"ming -- 2");
// DISPATCH_QUEUE_SERIAL
dispatch_queue_t queue = dispatch_queue_create("mingming2", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
NSLog(@"ming -- 3");
NSLog(@"ming -- 4");
NSLog(@"ming -- 13");
NSLog(@"ming -- 14");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"ming -- 5");
[NSThread sleepForTimeInterval:5.0];
NSLog(@"ming -- 6");
});
NSLog(@"ming -- 7");
});
NSLog(@"ming -- 8");
NSLog(@"+=====+++++++++++++=============+++++++++++++++++++++++++====");
}
2、异步全局队列
- (void)viewDidLoad {
[super viewDidLoad];
[self test2];
}
/** 输出
* 1 2 8 3 4 7 5 6
*/
- (void)test2{
NSLog(@"ming -- 1");
NSLog(@"ming -- 2");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"ming -- 3");
NSLog(@"ming -- 4");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"ming -- 5");
[NSThread sleepForTimeInterval:5.0];
NSLog(@"ming -- 6");
});
NSLog(@"ming -- 7" );
});
NSLog(@"ming -- 8");
NSLog(@"+=====+++++++++++++=============+++++++++++++++++++++++++====");
}
-
补充两张dispatch_async图片:
-
总结:异步同时执行,并没有明显的先后顺序之分。
3、同步全局队列
- (void)viewDidLoad {
[super viewDidLoad];
[self test3];
}
/** 输出
* 1 2 3 4 7 8 5 6
*/
- (void)test3{
NSLog(@"ming -- 1");
NSLog(@"ming -- 2");
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
NSLog(@"ming -- 3");
NSLog(@"ming -- 4");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"ming -- 5");
[NSThread sleepForTimeInterval:5.0];
NSLog(@"ming -- 6");
});
NSLog(@"ming -- 7");
});
NSLog(@"ming -- 8");
}
总结,通过三处代码。通过同步/异步、串行/并发(全局/主线程)的组合,可以看出,执行代码的先后顺序最外层的dispatch_sync(同步)和dispatch_async(异步)。
dispatch_sync(同步)——同步的话就按顺序执行,先执行最外层的dispatch_sync的代码,再执行NSLog(@"ming -- 8");,最后执行 dispatch_async(dispatch_get_main_queue(), ^{代码});里面的代码。
dispatch_async(异步)——异步的话就不按顺序执行,先执行NSLog(@"ming -- 8");,再执行最外层的dispatch_async的代码,最后执行 dispatch_async(dispatch_get_main_queue(), ^{代码});里面的代码。
Tip
值得注意的是dispatch_sync(同步)的时候,如果是
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
dispatch_sync(dispatch_get_main_queue(), ^{});
}
这种情况,在同步线程执行主队列,会造成死锁.如下图代码所示:
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
NSLog(@"ming -- 3");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"ming -- 5");
[NSThread sleepForTimeInterval:5.0];
NSLog(@"ming -- 6");
});
NSLog(@"ming -- 7");
});