-
前言
- 多線程代碼執(zhí)行先后的是怎樣的呢?我認為執(zhí)行代碼的先后順序最外層的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圖片:
-
總結(jié):異步同時執(zhí)行,并沒有明顯的先后順序之分前方。
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");
}
總結(jié),通過三處代碼惠险。通過同步/異步、串行/并發(fā)(全局/主線程)的組合抒线,可以看出班巩,執(zhí)行代碼的先后順序最外層的dispatch_sync(同步)和dispatch_async(異步)。
dispatch_sync(同步)——同步的話就按順序執(zhí)行,先執(zhí)行最外層的dispatch_sync的代碼抱慌,再執(zhí)行NSLog(@"ming -- 8");逊桦,最后執(zhí)行 dispatch_async(dispatch_get_main_queue(), ^{代碼});里面的代碼。
dispatch_async(異步)——異步的話就不按順序執(zhí)行抑进,先執(zhí)行NSLog(@"ming -- 8");强经,再執(zhí)行最外層的dispatch_async的代碼,最后執(zhí)行 dispatch_async(dispatch_get_main_queue(), ^{代碼});里面的代碼寺渗。
Tip
值得注意的是dispatch_sync(同步)的時候匿情,如果是
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
dispatch_sync(dispatch_get_main_queue(), ^{});
}
這種情況,在同步線程執(zhí)行主隊列信殊,會造成死鎖.如下圖代碼所示:
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");
});