二、任務(wù)、隊(duì)列之間的嵌套

此文章只做學(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ā)嵌套異步

同步并發(fā)嵌套異步1
同步并發(fā)嵌套異步2

分析:

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í)操作

添加耗時(shí)操作
輸出結(jié)果

結(jié)論:begin?任務(wù)1?任務(wù)3?任務(wù)2?end?或者?begin?任務(wù)1?任務(wù)2?任務(wù)3?end?


二、?同步并發(fā)嵌套同步

同步并發(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è)的打印順序是不可控的

結(jié)果1

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

結(jié)果2

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

異步并發(fā)嵌套異步

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

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

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


五、?????異步串行嵌套異步

異步串行嵌套異步1
異步串行嵌套異步2

分析:

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ā)嵌套同步

異步并發(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ā)嵌套異步

異步并發(fā)嵌套異步

分析:

1.????begin,接下來(lái)是一個(gè)異步

2.????所以end?的輸出順序不可控

3.????由于都是異步的并且都是并發(fā)隊(duì)列,所以任務(wù)1、任務(wù)2、任務(wù)3的順序也都是不可控的,但是任務(wù)1肯定是在任務(wù)2、任務(wù)3前邊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容