GCD隊列理解
先拋總結(jié)點:
1.并行隊列要并行執(zhí)行顽照,其實也是通過開辟多個子線程實現(xiàn)的分冈;那么當(dāng)并行隊列遇到?jīng)]法開辟多個子線程只估,那么他就沒法達(dá)到并行的目的,例如dispatch_sync(concurrentQueue
掺喻,理解了這點芭届,這塊知識就很好記住了
2.dispatch_async
會開辟一個線程執(zhí)行储矩,dispatch_sync
當(dāng)前線程執(zhí)行
3.dispatch_get_main_queue()上的任務(wù)肯定是在主線程上跑
再看下面的詳述的好理解了
/// 在主線程執(zhí)行這個,這時候主隊里有一個任務(wù)1,就是這一塊
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"1");
});
然后這個里面又把block任務(wù)褂乍,也就是NSLog(@"1")持隧;當(dāng)成任務(wù)2吧,再放到主隊列
那么這時候主隊列就有任務(wù)1和任務(wù)2
任務(wù)1執(zhí)行完的定義
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"1");
});
這一塊都執(zhí)行完逃片,也就是NSLog(@"1")也得執(zhí)行完
所以這時候任務(wù)2(NSLog(@"1"))要執(zhí)行屡拨,又得等任務(wù)1執(zhí)行完,所以就死鎖了
并行隊列和串行隊里的任務(wù)在哪個線程執(zhí)行褥实,是取決于dispatch_async
和dispatch_sync
的呀狼,
dispatch_async
會開辟一個線程執(zhí)行,dispatch_sync
當(dāng)前線程執(zhí)行
dispatch_async(concurrentQueue
是開辟多個子線程執(zhí)行的损离,并且block
是并行的
dispatch_async(serialQueue,
是開辟一個子線程執(zhí)行哥艇,而且block
都是有序執(zhí)行的
所以串行隊列、并行隊列和dispatch_async
結(jié)合僻澎,首先任務(wù)一定是在子線程執(zhí)行
隊列的影響只是貌踏,并行隊列會開辟多個子線程,達(dá)到并行的目的怎棱;串行隊列就按照dispatch_async
的來哩俭,就在新開辟的這個子線程上搞,達(dá)到串行的目的
dispatch_async(dispatch_get_main_queue()
是在主線程中執(zhí)行的拳恋,并且block
的串行的凡资,也就是說,主隊列的任務(wù)一定是在主線程上跑
dispatch_sync(concurrentQueue
和dispatch_sync(serialQueue
都是在當(dāng)前線程上串行的執(zhí)行谬运,因為dispatch_sync
不會去開辟新的線程隙赁,所以就算是dispatch_sync(concurrentQueue
也不會并行執(zhí)行
隊列有三種:dispatch_get_main_queue,dispatch_queue_create梆暖,dispatch_get_global_queue
測試下伞访,加深理解
// 并行隊列 異步+同步
- (void)test1
{
dispatch_queue_t queue = dispatch_queue_create("1111", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
// 異步開辟一個子線程
dispatch_async(queue, ^{
NSLog(@"2");
// 同步,卡住當(dāng)前線程轰驳,知道3輸出厚掷,所以3->4
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
// 并行隊列 異步+異步
- (void)test2
{
dispatch_queue_t queue = dispatch_queue_create("1111", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
// 異步開辟一個子線程
dispatch_async(queue, ^{
NSLog(@"2");
// 再開辟一個子線程,所以先4再3
dispatch_async(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
// 串行隊列 異步+異步
- (void)test3
{
dispatch_queue_t queue = dispatch_queue_create("1111", DISPATCH_QUEUE_SERIAL);
NSLog(@"1");
// 開辟一個子線程
dispatch_async(queue, ^{
NSLog(@"2");
// 再開辟一個子線程级解,首先這里要明白冒黑,2,3勤哗,4算是串行隊列中的一個任務(wù)抡爹,因為3是新開了一個子線程,又不會卡住芒划,所以輸出2冬竟,4這個任務(wù)就算完成了欧穴,然后新開的這個子線程再執(zhí)行3
dispatch_async(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
// 串行隊列 異步+同步
- (void)test4
{
dispatch_queue_t queue = dispatch_queue_create("1111", DISPATCH_QUEUE_SERIAL);
NSLog(@"1");
// 開辟一個子線程
dispatch_async(queue, ^{
NSLog(@"2");
// 2,3泵殴,4是同一個任務(wù)涮帘,sync不會開辟線程,所以他又將3加入到串行隊列中笑诅,這時候隊列第一個任務(wù)是2焚辅,3,4苟鸯,第二個任務(wù)是3同蜻,因為他得把2,3早处,4執(zhí)行完才會輪到第二個任務(wù)湾蔓,問題是他要執(zhí)行完,輸出這個3砌梆,這個3是在第二個任務(wù)里面的默责,所以死鎖了
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}