此文章只做學(xué)習(xí)筆記之用,如有錯(cuò)誤,歡迎留言批評(píng)指正!??!
?GCD之任務(wù)、隊(duì)列之間的相互嵌套
注意:
同步、異步:針對(duì)的是線程
?串行、并行:針對(duì)的是隊(duì)列
一條線程同一時(shí)間只能執(zhí)行一個(gè)任務(wù),同步的話,不會(huì)開(kāi)辟線程,所以任務(wù)只會(huì)在主線程里邊進(jìn)行,因此,同步任務(wù)里邊,不管是串行隊(duì)列還是并行隊(duì)列,都只能是一個(gè)任務(wù)完成之后,才會(huì)執(zhí)行下個(gè)任務(wù)。
一、?同步并發(fā)嵌套異步


分析:
1.????先輸出begin?(這個(gè)毋庸置疑)
2.????接下來(lái),是一個(gè)同步并發(fā)任務(wù)(簡(jiǎn)稱block1),而同步任務(wù)會(huì)阻塞當(dāng)前線程,所以只有當(dāng)block里邊的任務(wù)執(zhí)行完之后才會(huì)執(zhí)行?任務(wù)end?所以end?排在最后邊
3.????block1中有包含三個(gè)小任務(wù)?任務(wù)1、block2、任務(wù)3,而block2中只有一個(gè)任務(wù)2
4.????block1中任務(wù)的執(zhí)行順序肯定是先輸出任務(wù)1,這個(gè)就不啰嗦了。接下來(lái)是block2,而block2?是一個(gè)異步的,所以不會(huì)阻塞當(dāng)前線程,由于是異步的,所以可能會(huì)開(kāi)辟一條新線程運(yùn)行任務(wù)2
5.????因?yàn)楫惒經(jīng)]有阻塞當(dāng)前線程,所以block2這個(gè)任務(wù)有沒(méi)有完成不會(huì)影響任務(wù)3的執(zhí)行,因此任務(wù)3?可能會(huì)在任務(wù)2之前輸出。當(dāng)然也有可能任務(wù)2在前,任務(wù)3在后。
6.????接下來(lái)上圖,在任務(wù)3之前模擬一個(gè)耗時(shí)操作


結(jié)論:begin?任務(wù)1?任務(wù)3?任務(wù)2?end?或者?begin?任務(wù)1?任務(wù)2?任務(wù)3?end?
二、?同步并發(fā)嵌套同步

分析:應(yīng)為都是同步,所以每個(gè)任務(wù)都不會(huì)開(kāi)辟新線程?都會(huì)阻塞當(dāng)前線程,任務(wù)一個(gè)接一個(gè)執(zhí)行,所以無(wú)論是否添加耗時(shí)操作,結(jié)果都一樣
結(jié)論:輸出結(jié)果就是?begin?->任務(wù)1?->任務(wù)2?->任務(wù)3?->end
三、同步串行嵌套異步

隊(duì)列是串行隊(duì)列
同步串行隊(duì)列函數(shù)–>block1
異步串行隊(duì)列函數(shù)–>block2
分析:
1.????先輸出begin?
2.????接下來(lái)碰到一個(gè)同步函數(shù)(block1),不會(huì)開(kāi)辟線程,阻塞當(dāng)前線程,打印?任務(wù)1
3.????然后碰到異步函數(shù)(block2)會(huì)開(kāi)辟新線程,所以會(huì)把這個(gè)異步串行隊(duì)列函數(shù)(也就是block2)放到子線程中去運(yùn)行,因?yàn)槭谴嘘?duì)列,所以在同步串行隊(duì)列函數(shù)(也就是block1)運(yùn)行完之前block2任務(wù)不會(huì)執(zhí)行,因此會(huì)先打印?任務(wù)3
4.????block1?執(zhí)行完成后,可能會(huì)打印end?也可能會(huì)打印任務(wù)2?這兩個(gè)的打印順序是不可控的

在end之前添加一個(gè)耗時(shí)操作,則打印結(jié)果是這樣的:

四、?????同步串行嵌套同步

運(yùn)行結(jié)果:

很明顯:死鎖,也就是兩個(gè)任務(wù)相互等待(block2?等待block1?完成,而block1?又在等待block2?完成)
五、?????異步串行嵌套異步


分析:
1.????begin?先輸出
2.????接下來(lái)是一個(gè)異步串行隊(duì)列函數(shù)(block1),由于是異步的,不會(huì)阻塞當(dāng)前線程,所以block1?和end?的輸出順序就是不可控的,同理block2?和end的輸出順序也是不可控的。
3.????因?yàn)槭谴嘘?duì)列,任務(wù)會(huì)一個(gè)一個(gè)執(zhí)行,任務(wù)2的輸出一定是在任務(wù)3后邊,即使任務(wù)3前邊添加了耗時(shí)操作
結(jié)論:
?由于是異步的所以輸出順序就會(huì)變得不可控,下面列出集中輸出順序,以供參考:
①.?????begin –?任務(wù)1 –?任務(wù)3 – end –?任務(wù)2
②.?????begin – end –?任務(wù)1 –?任務(wù)3 –?任務(wù)2
③.?????begin –?任務(wù)1 –?任務(wù)3 –?任務(wù)2 – end?
④.?????begin –?任務(wù)1 – end –?任務(wù)3 –?任務(wù)2?
六、?????異步串行嵌套同步(死鎖)

分析:
1.????begin
2.????接下來(lái)遇到異步函數(shù),將任務(wù)1、同步線程(block2)、任務(wù)3?添加到了串行隊(duì)列中。由于是異步線程,所以end?可以不必等待直接block1中的任務(wù)完成
3.????所以?end?和任務(wù)1?的輸出位置就是不可控的
4.????任務(wù)1?輸出之后,遇到同步線程,將任務(wù)2添加到串行隊(duì)列中
5.????由于任務(wù)3?比任務(wù)2?先添加到串行隊(duì)列,所以,任務(wù)2?要等到任務(wù)3完成之后,才能執(zhí)行。但是任務(wù)2是所在的同步線程會(huì)發(fā)生阻塞,所以任務(wù)3?又必須等任務(wù)2執(zhí)行完成之后再執(zhí)行,因此,就會(huì)陷入到無(wú)限等待中,造成死鎖。
相關(guān)鏈接:http://ios.jobbole.com/82622/(此文介紹的比較通俗易懂,沒(méi)看明白的小伙伴可以查看此篇文章)
七、?????異步并發(fā)嵌套同步

分析:
1.????begin?,接下來(lái)是遇到一個(gè)異步并發(fā)隊(duì)列,所以end?的輸出則不受影響
2.????在block1中?一次添加了任務(wù)1?、同步并發(fā)隊(duì)列(block2)、任務(wù)3
3.????然后輸出任務(wù)1?接下來(lái)遇到一個(gè)同步線程,將任務(wù)2添加到并發(fā)隊(duì)列中,由于同步會(huì)阻塞當(dāng)前線程,所以任務(wù)3?必須等到任務(wù)2輸出之后,才能輸出,即使在任務(wù)2里邊添加耗時(shí)操作,任務(wù)3的輸出一定是在任務(wù)2之后
4.????end的輸出順序不可控
八、?????異步并發(fā)嵌套異步

分析:
1.????begin,接下來(lái)是一個(gè)異步
2.????所以end?的輸出順序不可控
3.????由于都是異步的并且都是并發(fā)隊(duì)列,所以任務(wù)1、任務(wù)2、任務(wù)3的順序也都是不可控的,但是任務(wù)1肯定是在任務(wù)2、任務(wù)3前邊