并行、串行、異步、同步的加深理解
單個理解:
并行:就是隊列里面的任務(代碼塊,block)不是一個個執行,而是同時執行,不存在先后順序
串行:隊列里面的任務一個接著一個執行,第一個執行完了才能輪到第二個
異步:具有新開線程的能力
同步:不具備有新開線程的能力,只能在當前線程執行任務(所以任務只能一個挨著一個執行,而不能同時進行)
串起來理解:
并行+異步:就是真正的并發,新開有有多個線程處理任務,任務并發執行(不按順序執行)
串行+異步:新開一個線程,任務一個接一個執行,上一個任務處理完畢,下一個任務才可以被執行
并行+同步:不新開線程,任務一個接一個執行
串行+同步:不新開線程,任務一個接一個執行
? 這里不得不說一下,之前看了這篇博客
http://www.cnblogs.com/ziyi--caolu/p/4900650.html 該作者成功的將我繞進了里面,其實歸根究底,只要是在同步環境中,并行和串行確實就可以這么理解,
即并行+同步 和 串行+同步 都是不新開線程,并且任務一個接一個執行
下面是具體代碼示例:
一:異步并行隊列內回調同步串行隊列
- (void)exampleFirst {
dispatch_queue_t queue = dispatch_queue_create("com.hao123.www", DISPATCH_QUEUE_SERIAL);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"外部---11 %@",[NSThread currentThread]);
dispatch_sync(queue, ^{
//打印結果與主隊列bingxingyibuqiantaozhu函數保持一致
NSLog(@"11 %@",[NSThread currentThread]);
});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"外部---22 %@",[NSThread currentThread]);
dispatch_sync(queue, ^{
NSLog(@"22 %@",[NSThread currentThread]);
});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"外部---33 %@",[NSThread currentThread]);
dispatch_sync(queue, ^{
NSLog(@"33 %@",[NSThread currentThread]);
});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"外部---44 %@",[NSThread currentThread]);
dispatch_sync(queue, ^{
NSLog(@"44 %@",[NSThread currentThread]);
});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"外部---55 %@",[NSThread currentThread]);
dispatch_sync(queue, ^{
NSLog(@"55 %@",[NSThread currentThread]);
});
});
}
打印結果
2017-09-08 14:29:24.407 GcdInsightTest[63582:2978456] 外部---44 <NSThread: 0x608000072780>{number = 6, name = (null)}
2017-09-08 14:29:24.407 GcdInsightTest[63582:2978364] 外部---11 <NSThread: 0x608000070f40>{number = 3, name = (null)}
2017-09-08 14:29:24.407 GcdInsightTest[63582:2978366] 外部---33 <NSThread: 0x600000076380>{number = 5, name = (null)}
2017-09-08 14:29:24.407 GcdInsightTest[63582:2978363] 外部---22 <NSThread: 0x600000072f00>{number = 4, name = (null)}
2017-09-08 14:29:24.407 GcdInsightTest[63582:2978457] 外部---55 <NSThread: 0x608000073340>{number = 7, name = (null)}
2017-09-08 14:29:24.407 GcdInsightTest[63582:2978456] 44 <NSThread: 0x608000072780>{number = 6, name = (null)}
2017-09-08 14:29:24.407 GcdInsightTest[63582:2978364] 11 <NSThread: 0x608000070f40>{number = 3, name = (null)}
2017-09-08 14:29:24.408 GcdInsightTest[63582:2978366] 33 <NSThread: 0x600000076380>{number = 5, name = (null)}
2017-09-08 14:29:24.408 GcdInsightTest[63582:2978363] 22 <NSThread: 0x600000072f00>{number = 4, name = (null)}
2017-09-08 14:29:24.408 GcdInsightTest[63582:2978457] 55 <NSThread: 0x608000073340>{number = 7, name = (null)}
二:異步并行內回調同步并行隊列
- (void)exampleSecond {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"外部---11 %@",[NSThread currentThread]);
//對比異步并行回調同步串行,可以看出當外部異步并行隊列未執行完畢時,有可能內部同步并行隊列已經開始執行了
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"11 %@",[NSThread currentThread]);
});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"外部---22 %@",[NSThread currentThread]);
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"22 %@",[NSThread currentThread]);
});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"外部---33 %@",[NSThread currentThread]);
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"33 %@",[NSThread currentThread]);
});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"外部---44 %@",[NSThread currentThread]);
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"44 %@",[NSThread currentThread]);
});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"外部---55 %@",[NSThread currentThread]);
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"55 %@",[NSThread currentThread]);
});
});
}
打印結果
2017-09-08 14:34:59.192 GcdInsightTest[64242:2984344] 外部---11 <NSThread: 0x608000263040>{number = 13, name = (null)}
2017-09-08 14:34:59.192 GcdInsightTest[64242:2984353] 外部---22 <NSThread: 0x608000262480>{number = 17, name = (null)}
2017-09-08 14:34:59.192 GcdInsightTest[64242:2984111] 外部---33 <NSThread: 0x608000073980>{number = 12, name = (null)}
2017-09-08 14:34:59.192 GcdInsightTest[64242:2984345] 外部---55 <NSThread: 0x60000007f1c0>{number = 16, name = (null)}
2017-09-08 14:34:59.192 GcdInsightTest[64242:2984346] 外部---44 <NSThread: 0x608000074d40>{number = 14, name = (null)}
2017-09-08 14:34:59.193 GcdInsightTest[64242:2984344] 11 <NSThread: 0x608000263040>{number = 13, name = (null)}
2017-09-08 14:34:59.194 GcdInsightTest[64242:2984353] 22 <NSThread: 0x608000262480>{number = 17, name = (null)}
2017-09-08 14:34:59.194 GcdInsightTest[64242:2984111] 33 <NSThread: 0x608000073980>{number = 12, name = (null)}
2017-09-08 14:34:59.194 GcdInsightTest[64242:2984345] 55 <NSThread: 0x60000007f1c0>{number = 16, name = (null)}
2017-09-08 14:34:59.194 GcdInsightTest[64242:2984346] 44 <NSThread: 0x608000074d40>{number = 14, name = (null)}
根據兩段例子的打印結果,可以顯而易見的得出結論:
一:由于外部是異步并行隊列,所以外部打印結果不按順序執行。
二:當外部所有隊列執行完畢,內部隊列才開始執行。
三:其內部的隊列將與外部隊列順序保持一致,無論異步并行隊列內回調的是同步串行隊列,還是同步并行隊列,只有當外部隊列執行完畢,接下來內部隊列才會在同一個線程繼續執行直到任務結束。
根據第三條可以得出結論:
并行+同步:不新開線程,任務一個接一個執行
串行+同步:不新開線程,任務一個接一個執行
這兩句話沒毛病~