同步、異步:表示開辟新線程的能力雇锡。
串行逛钻、并行:表示隊(duì)列的調(diào)度任務(wù)的能力。
任務(wù):就是執(zhí)行操作的意思锰提,換句話說就是你在線程中執(zhí)行的那段代碼曙痘。在 GCD 中是放在 block 中的。執(zhí)行任務(wù)有兩種方式:『同步執(zhí)行』 和 『異步執(zhí)行』立肘。兩者的主要區(qū)別是:是否等待隊(duì)列的任務(wù)執(zhí)行結(jié)束边坤,以及是否具備開啟新線程的能力。
同步執(zhí)行(sync):
–同步添加任務(wù)到指定的隊(duì)列中谅年,在添加的任務(wù)執(zhí)行結(jié)束之前茧痒,會一直等待,直到隊(duì)列里面的任務(wù)完成之后再繼續(xù)執(zhí)行融蹂。
–只能在當(dāng)前線程中執(zhí)行任務(wù)文黎,不具備開啟新線程的能力。
異步執(zhí)行(async)
–異步添加任務(wù)到指定的隊(duì)列中殿较,它不會做任何等待耸峭,可以繼續(xù)執(zhí)行任務(wù)。
–可以在新的線程中執(zhí)行任務(wù)淋纲,具備開啟新線程的能力劳闹。
注意:異步執(zhí)行雖然具有開啟新線程的能力,但是并不一定開啟新線程洽瞬。這跟任務(wù)所指定的隊(duì)列類型有關(guān)本涕。
隊(duì)列(Dispatch Queue):這里的隊(duì)列指執(zhí)行任務(wù)的等待隊(duì)列,即用來存放任務(wù)的隊(duì)列伙窃。隊(duì)列是一種特殊的線性表菩颖,采用 FIFO(先進(jìn)先出)的原則,即新任務(wù)總是被插入到隊(duì)列的末尾为障,而讀取任務(wù)的時(shí)候總是從隊(duì)列的頭部開始讀取晦闰。
串行隊(duì)列(Serial Dispatch Queue):
– 每次只有一個(gè)任務(wù)被執(zhí)行放祟。讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行。(只開啟一個(gè)線程呻右,一個(gè)任務(wù)執(zhí)行完畢后跪妥,再執(zhí)行下一個(gè)任務(wù))
并發(fā)隊(duì)列(Concurrent Dispatch Queue):
-可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行。(可以開啟多個(gè)線程声滥,并且同時(shí)執(zhí)行任務(wù))
注意:并發(fā)隊(duì)列 的并發(fā)功能只有在異步(dispatch_async)方法下才有效眉撵。
『主線程』中,『不同隊(duì)列』+『不同任務(wù)』簡單組合的區(qū)別:
- 注意:從上邊可看出: 『主線程』 中調(diào)用 『主隊(duì)列』+『同步執(zhí)行』 會導(dǎo)致死鎖問題落塑。這是因?yàn)?主隊(duì)列中追加的同步任務(wù) 和 主線程本身的任務(wù) 兩者之間相互等待纽疟,阻塞了 『主隊(duì)列』,最終造成了主隊(duì)列所在的線程(主線程)死鎖問題憾赁。
而如果我們在 『其他線程』 調(diào)用 『主隊(duì)列』+『同步執(zhí)行』污朽,則不會阻塞 『主隊(duì)列』,自然也不會造成死鎖問題缠沈。最終的結(jié)果是:不會開啟新線程膘壶,串行執(zhí)行任務(wù)。
除了上邊提到的『主線程』中調(diào)用『主隊(duì)列』+『同步執(zhí)行』會導(dǎo)致死鎖問題洲愤。實(shí)際在使用『串行隊(duì)列』的時(shí)候颓芭,也可能出現(xiàn)阻塞『串行隊(duì)列』所在線程的情況發(fā)生,從而造成死鎖問題柬赐。這種情況多見于同一個(gè)串行隊(duì)列的嵌套使用亡问。
比如下面代碼這樣:在『異步執(zhí)行』+『串行隊(duì)列』的任務(wù)中,又嵌套了『當(dāng)前的串行隊(duì)列』肛宋,然后進(jìn)行『同步執(zhí)行』州藕。
dispatch_queue_t queue = dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{ // 異步執(zhí)行 + 串行隊(duì)列
dispatch_sync(queue, ^{ // 同步執(zhí)行 + 當(dāng)前串行隊(duì)列
// 追加任務(wù) 1
[NSThread sleepForTimeInterval:2]; // 模擬耗時(shí)操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印當(dāng)前線程
});
});
執(zhí)行上面的代碼會導(dǎo)致 串行隊(duì)列中追加的任務(wù) 和 串行隊(duì)列中原有的任務(wù) 兩者之間相互等待,阻塞了『串行隊(duì)列』酝陈,最終造成了串行隊(duì)列所在的線程(子線程)死鎖問題床玻。
主隊(duì)列造成死鎖也是基于這個(gè)原因,所以沉帮,這也進(jìn)一步說明了主隊(duì)列其實(shí)并不特殊锈死。
關(guān)于 『隊(duì)列中嵌套隊(duì)列』這種復(fù)雜情況,這里也簡單做一個(gè)總結(jié)穆壕。不過這里只考慮同一個(gè)隊(duì)列的嵌套情況
『不同隊(duì)列』+『不同任務(wù)』 組合待牵,以及 『隊(duì)列中嵌套隊(duì)列』 使用的區(qū)別: