筆者也是在邊學(xué)習(xí)邊整理,有不對的地方歡迎指出
?GCD的兩種類型:
(1)并發(fā)隊列(Concurrent Dispatch Queue)
? 可以讓多個任務(wù)并發(fā)(同時)執(zhí)行(自動開啟多個線程同時執(zhí)行任務(wù))并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效
(2)串行隊列(Serial Dispatch Queue)
?讓任務(wù)一個接著一個地執(zhí)行(一個任務(wù)執(zhí)行完畢后,再執(zhí)行下一個任務(wù))

將任務(wù)添加到隊列中,GCD會自動將隊列中的任務(wù)取出,放到對應(yīng)的線程中執(zhí)行
提示:任務(wù)的取出遵循隊列的FIFO原則:先進先出,后進后出
同步和異步?jīng)Q定了要不要開啟新的線程
同步:在當(dāng)前線程中執(zhí)行任務(wù),不具備開啟新線程的能力
異步:在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力
并發(fā)和串行決定了任務(wù)的執(zhí)行方式
并發(fā):多個任務(wù)并發(fā)(同時)執(zhí)行
串行:一個任務(wù)執(zhí)行完畢后,再執(zhí)行下一個任務(wù)
(1)用異步函數(shù)往并發(fā)隊列中添加任務(wù)
?總結(jié):同時開啟多個子線程
(2)用異步函數(shù)往串行隊列中添加任務(wù)
?總結(jié):會開啟線程,但是只開啟一個線程
(3)用同步函數(shù)往并發(fā)隊列中添加任務(wù)
?總結(jié):不會開啟新的線程,并發(fā)隊列失去了并發(fā)的功能
(4)用同步函數(shù)往串行隊列中添加任務(wù)
?總結(jié):不會開啟新的線程
說明:同步函數(shù)不具備開啟線程的能力,無論是什么隊列都不會開啟線程;異步函數(shù)具備開啟線程的能力,開啟幾條線程由隊列決定(串行隊列只會開啟一條新的線程,并發(fā)隊列會開啟多條線程)。
同步函數(shù)
(1)并發(fā)隊列:不會開線程
(2)串行隊列:不會開線程
異步函數(shù)
(1)并發(fā)隊列:能開啟N條線程
(2)串行隊列:開啟1條線程
dispatch_async(queue,block)? async 異步隊列,dispatch_async 函數(shù)會立即返回, block會在后臺異步執(zhí)行。
dispatch_sync(queue,block)? sync 同步隊列,dispatch_sync 函數(shù)不會立即返回,及阻塞當(dāng)前線程,等待 block同步執(zhí)行完成。
下面上代碼,可以理解的更透徹一些:
(1)同步串行隊列
這里加sleep方便從運行結(jié)果更好的看出區(qū)別

可以看出,這里的時間間隔就是sleep,也就是說會按順序添加到隊列中,并且只能等上一個任務(wù)結(jié)束才能進行下一個任務(wù),所有的操作都是在主線程中進行,并不會開辟新的子線程。

(2)同步并發(fā)隊列
從運行結(jié)果顯而易見,同步串行和同步并發(fā)結(jié)果是相同的,也是上一個任務(wù)結(jié)束才能進行下一個任務(wù),也是在主線程中進行,并且也沒有開辟新的子線程,也就是說同步函數(shù)不具備開啟線程的能力。


(3)異步串行隊列

從結(jié)果可以看出,同步和異步串行隊列的區(qū)別主要在于開辟子線程的能力,在同步串行隊列中,所有的任務(wù)都是在主線程執(zhí)行,在異步串行隊列中,會開辟一個新的子線程,不論有多少個任務(wù),都只會開辟一個子線程。

(4)異步并發(fā)隊列

從結(jié)果可以看出,異步并發(fā)隊列是多個任務(wù)同時執(zhí)行,并且會根據(jù)任務(wù)的多少開辟多個子線程,可以把sleep去掉會發(fā)現(xiàn),輸出的順序是無序的。

(5)GCD延時操作


(6)隊列組

首先創(chuàng)建隊列組,把需要執(zhí)行的任務(wù)都放到隊列組里,notify是監(jiān)聽隊列組中所有任務(wù)完成之后才會調(diào)用的。

死鎖問題(筆者也是根據(jù)自己的理解,有問題之處還望指出)
其實死鎖的原因就是線程之間相互阻塞(相互等待)
①
因為同步函數(shù)會等block塊執(zhí)行完成之后才接著往下執(zhí)行,執(zhí)行到圖中所示位置時,會在主線程新加入一個隊列,所以sync會等待block執(zhí)行完成之后在繼續(xù)往下執(zhí)行,但是sync在主線程中,而且是串行隊列,sync是后加入進來的,sync想執(zhí)行必須等主線程執(zhí)行完成,主線程等待sync返回,所以執(zhí)行到此處就會造成死鎖,不會繼續(xù)往下執(zhí)行了。簡單來說,就是sync等待主線程執(zhí)行完成, 主線程等待sync函數(shù)返回。


②
對比下面圖的運行結(jié)果,可以看出,異步函數(shù)中不會等待block執(zhí)行完成,會立刻返回,兩個同步函數(shù)之間相互等待,造成死鎖。

從輸出時間可以看出,1和2幾乎同時執(zhí)行,因為是在異步函數(shù)中,當(dāng)執(zhí)行到2的sync時1存在兩種情況:(1)執(zhí)行中 (2)已經(jīng)執(zhí)行完成 ,而且主線程中并沒有執(zhí)行耗時操作,所以1和2同時完成;如果把2處改成sleep(3),那么就會出現(xiàn)前面說異步函數(shù)時出現(xiàn)的情況,輸出時間至少會差3秒;如果阻塞了主線程,2處的sync就會一直等待永遠都不會執(zhí)行。
