第七章、多線程相關(guān)

一、談?wù)剬?duì)GCD的認(rèn)識(shí)理解

Grand Central Dispatch(GCD),主要用于優(yōu)化應(yīng)用程序以支持多核處理器以及其他對(duì)稱多處理系統(tǒng)。它是一個(gè)在線程池模式的基礎(chǔ)上執(zhí)行的并發(fā)任務(wù)。

特點(diǎn):
1、GCD可用于多核的并行運(yùn)算
2、GCD會(huì)自動(dòng)利用更多的CPU內(nèi)核(比如雙核、四核)
3、GCD會(huì)自動(dòng)管理線程的生命周期(創(chuàng)建線程、調(diào)度任務(wù)、銷毀線程)
4、程序員只需要告訴GCD想要執(zhí)行什么任務(wù),不需要編寫任何線程管理代碼

執(zhí)行任務(wù)有兩種方式:同步執(zhí)行(sync)和異步執(zhí)行(async)。兩者的主要區(qū)別是:是否等待隊(duì)列的任務(wù)執(zhí)行結(jié)束,以及是否具備開啟新線程的能力。
  • 同步執(zhí)行(sync):

同步添加任務(wù)到指定的隊(duì)列中,在添加的任務(wù)執(zhí)行結(jié)束之前,會(huì)一直等待,直到隊(duì)列里面的任務(wù)完成之后再繼續(xù)執(zhí)行。
只能在當(dāng)前線程中執(zhí)行任務(wù),不具備開啟新線程的能力。

  • 異步執(zhí)行(async):

異步添加任務(wù)到指定的隊(duì)列中,它不會(huì)做任何等待,可以繼續(xù)執(zhí)行任務(wù)。
可以在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力。

GCD 中有兩種隊(duì)列:串行隊(duì)列和并發(fā)隊(duì)列。兩者都符合 FIFO(先進(jìn)先出)的原則。兩者的主要區(qū)別是:執(zhí)行順序不同,以及開啟線程數(shù)不同。
  • 串行隊(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ù))

既然我們有兩種隊(duì)列(串行隊(duì)列/并發(fā)隊(duì)列),兩種任務(wù)執(zhí)行方式(同步執(zhí)行/異步執(zhí)行),那么我們就有了六種不同的組合方式:

1、同步執(zhí)行 + 并發(fā)隊(duì)列
在當(dāng)前線程中執(zhí)行任務(wù),不會(huì)開啟新線程,執(zhí)行完一個(gè)任務(wù),再執(zhí)行下一個(gè)任務(wù)。
2、異步執(zhí)行 + 并發(fā)隊(duì)列
可以開啟多個(gè)線程,任務(wù)交替(同時(shí))執(zhí)行。
3、同步執(zhí)行 + 串行隊(duì)列
不會(huì)開啟新線程,在當(dāng)前線程執(zhí)行任務(wù)。任務(wù)是串行的,執(zhí)行完一個(gè)任務(wù),再執(zhí)行下一個(gè)任務(wù)。
4、異步執(zhí)行 + 串行隊(duì)列
會(huì)開啟新線程,但是因?yàn)槿蝿?wù)是串行的,執(zhí)行完一個(gè)任務(wù),再執(zhí)行下一個(gè)任務(wù)。
5、同步執(zhí)行 + 主隊(duì)列
在不同線程中調(diào)用結(jié)果也是不一樣,在主線程中調(diào)用會(huì)出現(xiàn)死鎖,而在其他線程中則不會(huì)。
6、異步執(zhí)行 + 主隊(duì)列
不會(huì)開啟新線程,執(zhí)行完一個(gè)任務(wù),再執(zhí)行下一個(gè)任務(wù)。

二、談?wù)剬?duì)NSOperation、NSOperationQueue的認(rèn)識(shí)理解

NSOperationNSOperationQueue是基于GCD更高一層的封裝,完全面向?qū)ο蟆5潜菺CD更簡(jiǎn)單易用、代碼可讀性也更高。但是NSOperation是個(gè)抽象類,不能用來(lái)封裝操作。只有使用它的子類來(lái)封裝操作。(NSInvocationOperation、NSBlockOperation、自定義)

特點(diǎn):
1、可添加完成的代碼塊,在操作完成后執(zhí)行。
2、添加操作之間的依賴關(guān)系,方便的控制執(zhí)行順序。
3、設(shè)定操作執(zhí)行的優(yōu)先級(jí)。
4、可以很方便的取消一個(gè)操作的執(zhí)行。
5、使用KVO觀察對(duì)操作執(zhí)行狀態(tài)的更改:isExecuting、isFinished、isCancelled。

NSInvocationOperation:
在其他線程中單獨(dú)使用子類NSInvocationOperation,操作是在當(dāng)前調(diào)用的其他線程執(zhí)行的,并沒(méi)有開啟新線程。

NSBlockOperation:
一般情況下,如果一個(gè)NSBlockOperation對(duì)象封裝了多個(gè)操作。NSBlockOperation是否開啟新線程,取決于操作的個(gè)數(shù)。如果添加的操作的個(gè)數(shù)多,就會(huì)自動(dòng)開啟新線程。當(dāng)然開啟的線程數(shù)是由系統(tǒng)來(lái)決定的。

自定義繼承自NSOperation的子類:
在沒(méi)有使用NSOperationQueue、在主線程單獨(dú)使用自定義繼承自NSOperation的子類的情況下,是在主線程執(zhí)行操作,并沒(méi)有開啟新線程。

NSOperationQueue控制串行執(zhí)行、并發(fā)執(zhí)行
maxConcurrentOperationCount,叫做最大并發(fā)操作數(shù)。用來(lái)控制一個(gè)特定隊(duì)列中可以有多少個(gè)操作同時(shí)參與并發(fā)執(zhí)行。這里maxConcurrentOperationCount控制的不是并發(fā)線程的數(shù)量,而是一個(gè)隊(duì)列中同時(shí)能并發(fā)執(zhí)行的最大操作數(shù)。而且一個(gè)操作也并非只能在一個(gè)線程中運(yùn)行。
簡(jiǎn)單來(lái)說(shuō),當(dāng)最大并發(fā)操作數(shù)為1時(shí),操作是按順序串行執(zhí)行的,并且一個(gè)操作完成之后,下一個(gè)操作才開始執(zhí)行。當(dāng)最大操作并發(fā)數(shù)為2時(shí),操作是并發(fā)執(zhí)行的,可以同時(shí)執(zhí)行兩個(gè)操作。而開啟線程數(shù)量是由系統(tǒng)決定的,不需要我們來(lái)管理。

更多參考詳情點(diǎn)擊iOS 多線程:『NSOperation、NSOperationQueue』詳盡總結(jié)

三、如何保證線程安全?

1、nonatomic atomic:使用atomic多線程原子性控制,atomic的原理給setter加上鎖,getter不會(huì)加鎖。OC在定義屬性時(shí)有nonatomic和atomic兩種選擇
2、使用GCD實(shí)現(xiàn)atomic操作:給某字段的setter和getter方法加上同步隊(duì)列
3、使用NSLock
4、使用互斥鎖

?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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