先來說一個隊列和任務:
隊列分為串行和并行
任務的執(zhí)行分為同步和異步
這兩兩組合就成為了串行隊列同步執(zhí)行,串行隊列異步執(zhí)行,并行隊列同步執(zhí)行,并行隊列異步執(zhí)行
而異步是多線程的代名詞,異步在實際引用中會開啟新的線程,執(zhí)行耗時操作。
那我們先來知道一個非常重要的事情:
-------? 隊列只是負責任務的調度,而不負責任務的執(zhí)行?? ---------
------- 任務是在線程中執(zhí)行的? ---------
隊列和任務的特點:
隊列的特點:先進先出,排在前面的任務最先執(zhí)行,
串行隊列:任務按照順序被調度,前一個任務不執(zhí)行完畢,隊列不會調度
并行隊列:只要有空閑的線程,隊列就會調度當前任務,交給線程去執(zhí)行,不需要考慮前面是都有任務在執(zhí)行,只要有線程可以利用,隊列就會調度任務。
主隊列:專門用來在主線程調度任務的隊列,所以主隊列的任務都要在主線程來執(zhí)行,主隊列會隨著程序的啟動一起創(chuàng)建,我們只需get即可
全局隊列:是系統(tǒng)為了方便程序員開發(fā)提供的,其工作表現(xiàn)與并發(fā)隊列一致,那么全局隊列跟并發(fā)隊列的區(qū)別是什么呢?
1.全局隊列:無論ARC還是MRC都不需要考錄釋放,因為系統(tǒng)提供的我們只需要get就可以了
2.并發(fā)隊列:再MRC下,并發(fā)隊列創(chuàng)建出來后,需要手動釋放dispatch_release()
同步執(zhí)行:不會開啟新的線程,任務按順序執(zhí)行
異步執(zhí)行:會開啟新的線程,任務可以并發(fā)的執(zhí)行
那么有這么幾種組合
串行隊列同步執(zhí)行:綜合上面闡述的串行隊列的特點 --- 按順序執(zhí)行,同步:不會開啟新的線程,則串行隊列同步執(zhí)行只是按部就班的one by one執(zhí)行。
串行隊列異步執(zhí)行:雖然隊列中存放的是異步執(zhí)行的任務,但是結合串行隊列的特點,前一個任務不執(zhí)行完畢,隊列不會調度,所以串行隊列異步執(zhí)行也是one by one的執(zhí)行
并行隊列同步執(zhí)行:結合上面闡述的并行隊列的特點,和同步執(zhí)行的特點,可以明確的分析出來,雖然并行隊列可以不需等待前一個任務執(zhí)行完畢就可調度下一個任務,但是任務同步執(zhí)行不會開啟新的線程,所以任務也是one by one的執(zhí)行
并行隊列異步執(zhí)行:再上一條中說明了并行隊列的特點,而異步執(zhí)行是任務可以開啟新的線程,所以這中組合可以實現(xiàn)任務的并發(fā),再實際開發(fā)中也是經常會用到的
GCD實現(xiàn)原理:
GCD有一個底層線程池,這個池中存放的是一個個的線程。之所以稱為“池”,很容易理解出這個“池”中的線程是可以重用的,當一段時間后這個線程沒有被調用胡話,這個線程就會被銷毀。注意:開多少條線程是由底層線程池決、、、、、定的(線程建議控制再3~5條),池是系統(tǒng)自動來維護,不需要我們程序員來維護(看到這句話是不是很開心?)
而我們程序員需要關心的是什么呢?我們只關心的是向隊列中添加任務,隊列調度即可。
如果隊列中存放的是同步任務,則任務出隊后,底層線程池中會提供一條線程供這個任務執(zhí)行,任務執(zhí)行完畢后這條線程再回到線程池。這樣隊列中的任務反復調度,因為是同步的,所以當我們用currentThread打印的時候,就是同一條線程。
如果隊列中存放的是異步的任務,(注意異步可以開線程),當任務出隊后,底層線程池會提供一個線程供任務執(zhí)行,因為是異步執(zhí)行,隊列中的任務不需等待當前任務執(zhí)行完畢就可以調度下一個任務,這時底層線程池中會再次提供一個線程供第二個任務執(zhí)行,執(zhí)行完畢后再回到底層線程池中。
這樣就對線程完成一個復用,而不需要每一個任務執(zhí)行都開啟新的線程,也就從而節(jié)約的系統(tǒng)的開銷,提高了效率。在iOS7.0的時候,使用GCD系統(tǒng)通常只能開5~8條線程,iOS8.0以后,系統(tǒng)可以開啟很多條線程,但是實在開發(fā)應用中,建議開啟線程條數:3~5條最為合理。