GCD總結(jié)

前言

為了緩解主線程的壓力除了優(yōu)化算法惯裕,性能等一列措施之外玄叠,我們用的最多的應(yīng)該就是多線程欣尼,通過(guò)開辟一個(gè)分線程祸穷,讓一些耗時(shí)的操作在分線程完成來(lái)釋放主線程壓力性穿,這種方式簡(jiǎn)單也很高效。但線程并不是越多越好雷滚,開辟線程同樣需要消耗性能( 開辟新線程:主線程(1M),子線程(512k))需曾,但是實(shí)在開發(fā)應(yīng)用中,建議開啟線程條數(shù):3~5條最為合理祈远。

GCD實(shí)現(xiàn)原理:

GCD有一個(gè)底層線程池呆万,這個(gè)池中存放的是一個(gè)個(gè)的線程。之所以稱為“池”车份,很容易理解出這個(gè)“池”中的線程是可以重用的谋减,當(dāng)一段時(shí)間后這個(gè)線程沒有被調(diào)用胡話,這個(gè)線程就會(huì)被銷毀扫沼。注意:開多少條線程是由底層線程池決定的(線程建議控制再3~5條)出爹,池是系統(tǒng)自動(dòng)來(lái)維護(hù),不需要我們程序員來(lái)維護(hù)缎除,而我們程序員需要關(guān)心的是什么呢严就?我們只關(guān)心的是向隊(duì)列中添加任務(wù),隊(duì)列調(diào)度即可器罐。

1.隊(duì)列只是負(fù)責(zé)任務(wù)的調(diào)度梢为,而不負(fù)責(zé)任務(wù)的執(zhí)行

2.任務(wù)是在線程中執(zhí)行的

先來(lái)說(shuō)一個(gè)隊(duì)列和任務(wù):

隊(duì)列分為串行隊(duì)列與并行隊(duì)列

任務(wù)的執(zhí)行分為同步任務(wù)與異步任務(wù)

這兩兩組合就成為了串行隊(duì)列同步執(zhí)行,串行隊(duì)列異步執(zhí)行,并行隊(duì)列同步執(zhí)行铸董,并行隊(duì)列異步執(zhí)行

而異步是多線程的代名詞祟印,異步在實(shí)際引用中經(jīng)常會(huì)開啟新的線程,執(zhí)行耗時(shí)操作袒炉,這里為什么說(shuō)是經(jīng)常旁理,因?yàn)椴⒉皇撬械漠惒饺蝿?wù)都會(huì)開啟一個(gè)線程,這個(gè)問(wèn)題后面會(huì)具體說(shuō)道我磁。

隊(duì)列和任務(wù)的特點(diǎn):

隊(duì)列的特點(diǎn) :先進(jìn)先出孽文,排在前面的任務(wù)最先執(zhí)行,

串行隊(duì)列:任務(wù)按照順序被調(diào)度夺艰,前一個(gè)任務(wù)不執(zhí)行完畢芋哭,隊(duì)列不會(huì)調(diào)度

并行隊(duì)列:只要有空閑的線程,隊(duì)列就會(huì)調(diào)度當(dāng)前任務(wù)郁副,交給線程去執(zhí)行减牺,不需要考慮前面是都有任務(wù)在執(zhí)行,只要有線程可以利用存谎,隊(duì)列就會(huì)調(diào)度任務(wù)拔疚。

主隊(duì)列:專門用來(lái)在主線程調(diào)度任務(wù)的隊(duì)列,所以主隊(duì)列的任務(wù)都要在主線程來(lái)執(zhí)行既荚,主隊(duì)列會(huì)隨著程序的啟動(dòng)一起創(chuàng)建稚失,我們只需get即可。現(xiàn)將任務(wù)放在主隊(duì)列中恰聘,但是不是馬上執(zhí)行句各,等到主隊(duì)列中的其它所有除我們使用代碼添加到主隊(duì)列的任務(wù)都執(zhí)行完畢之后才會(huì)執(zhí)行我們使用代碼添加的任務(wù)。

全局隊(duì)列:是系統(tǒng)為了方便程序員開發(fā)提供的晴叨,其工作表現(xiàn)與并發(fā)隊(duì)列一致凿宾,那么全局隊(duì)列跟并發(fā)隊(duì)列的區(qū)別是什么呢?

1.全局隊(duì)列:無(wú)論ARC還是MRC都不需要考錄釋放兼蕊,因?yàn)橄到y(tǒng)提供的我們只需要get就可以了

2.并發(fā)隊(duì)列:再M(fèi)RC下初厚,并發(fā)隊(duì)列創(chuàng)建出來(lái)后,需要手動(dòng)釋放dispatch_release()

同步執(zhí)行:不會(huì)開啟新的線程孙技,任務(wù)按順序執(zhí)行产禾,當(dāng)一個(gè)任務(wù)沒有執(zhí)行完成,不會(huì)開始執(zhí)行新的任務(wù)绪杏。

異步執(zhí)行:會(huì)開啟新的線程,任務(wù)可以并發(fā)的執(zhí)行纽绍,當(dāng)一個(gè)任務(wù)開始執(zhí)行蕾久,下個(gè)任務(wù)不需要等待前置任務(wù)完成即可開始執(zhí)行。

今天研究的目錄

1.串行隊(duì)列里添加同步任務(wù)

2.串行隊(duì)列添加異步任務(wù)

3..并行隊(duì)列里添加同步任務(wù)

4.并行隊(duì)列添加異步任務(wù)

5.全局并發(fā)對(duì)列

6.主隊(duì)列

7.并行隊(duì)列里異步任務(wù)嵌套同步任務(wù)

8.并行隊(duì)列里異步任務(wù)嵌套異步任務(wù)

9.串行隊(duì)列里異步任務(wù)嵌套同步任務(wù)

10.串行隊(duì)列里異步任務(wù)嵌套異步任務(wù)

11.串行隊(duì)列里同步任務(wù)嵌套同步任務(wù)

12.延遲執(zhí)行

13.定時(shí)器

14.group之同步任務(wù)

15.group之異步任務(wù)

16.apply

17.barrier(柵欄)

18.信號(hào)量

接下來(lái)一個(gè)一個(gè)看

1.串行隊(duì)列里添加同步任務(wù)


首先串行隊(duì)列所有任務(wù)依次執(zhí)行拌夏,向串行隊(duì)列里添加同步任務(wù)僧著,同步任務(wù)特點(diǎn)履因,不會(huì)開啟線程并且當(dāng)前任務(wù)執(zhí)行完才會(huì)執(zhí)行下一個(gè)任務(wù),所以輸出順序?yàn)?盹愚,2栅迄,3。

2.串行隊(duì)列添加異步任務(wù)


從結(jié)果可以看到執(zhí)行順序還是依次執(zhí)行皆怕,雖然添加的是異步任務(wù)毅舆,造成這種現(xiàn)象是因?yàn)榇嘘?duì)列的特點(diǎn),就算你是異步任務(wù)但還是得按我的規(guī)矩來(lái)愈腾,和上面相比不同的是開辟了一個(gè)分線程去執(zhí)行憋活,因?yàn)楫惒饺蝿?wù)具備開啟分線程的能力,那么問(wèn)題來(lái)了虱黄,為什么三個(gè)異步任務(wù)只開啟一個(gè)分線程悦即?這是因?yàn)榇嘘?duì)列所有任務(wù)順序執(zhí)行,開啟三個(gè)也還是順序執(zhí)行橱乱,倒不如只開啟一個(gè)辜梳,畢竟開啟分線程也是消耗性能的。

3.并行隊(duì)列里添加同步任務(wù)


同步任務(wù)的特點(diǎn)泳叠,不會(huì)開啟新的線程并且當(dāng)前任務(wù)執(zhí)行完才能執(zhí)行下個(gè)任務(wù)作瞄,那么就算你是并發(fā)隊(duì)列也沒什么卵用了,只能依次執(zhí)行析二。

4.并行隊(duì)列添加異步任務(wù)


真正能實(shí)現(xiàn)并發(fā)操作的只有這情況粉洼,執(zhí)行順序是1,3叶摄,2属韧,開啟了三個(gè)線程來(lái)執(zhí)行任務(wù)

5.全局并發(fā)對(duì)列


系統(tǒng)提供的并發(fā)隊(duì)列,直接獲取就行蛤吓。

6.主隊(duì)列


主隊(duì)列不管異步還是同步宵喂,都不會(huì)開啟新的線程,只能在主線程執(zhí)行会傲。

7.并行隊(duì)列里異步任務(wù)嵌套同步任務(wù)


queue是一個(gè)并行隊(duì)列锅棕,首先調(diào)用dispatch_async函數(shù),將block添加到隊(duì)列里淌山,由于是異步任務(wù)所以會(huì)開啟一個(gè)分線程并且不用等到block的代碼執(zhí)行完就可以繼續(xù)往下走裸燎,所以結(jié)束和1誰(shuí)先執(zhí)行并不確定,在結(jié)束前將主線程休眠2秒泼疑,這樣1會(huì)先走德绿,執(zhí)行完1接著又調(diào)用dispatch_sync函數(shù),將block添加到隊(duì)列里,由于這是一個(gè)同步任務(wù)移稳,所以block會(huì)立刻執(zhí)行蕴纳,接著輸出2,當(dāng)主線程休眠結(jié)束會(huì)輸出結(jié)束个粱,結(jié)束和2誰(shuí)先執(zhí)行也是不確定的古毛,如果主線程休眠時(shí)間長(zhǎng),那么2先輸出都许,反之結(jié)束先輸出稻薇,之所以不確定,是因?yàn)?在分線程里梭稚,所以什么時(shí)候會(huì)執(zhí)行無(wú)法確定颖低。


8.并行隊(duì)列里異步任務(wù)嵌套異步任務(wù)


這個(gè)和上面那個(gè)并行隊(duì)列里異步任務(wù)嵌套異步任務(wù)運(yùn)行結(jié)果是一樣的,區(qū)別在于2上面在同步任務(wù)弧烤,這個(gè)是在異步任務(wù)里忱屑,一個(gè)馬上執(zhí)行,一個(gè)不確定暇昂。

9.串行隊(duì)列里異步任務(wù)嵌套同步任務(wù)


這個(gè)很簡(jiǎn)答莺戒,先走1還是先走結(jié)束都是不確定的,但我們?cè)俳Y(jié)束前加了一個(gè)主線程休眠急波,那么只會(huì)先走1,走完1之后又會(huì)向隊(duì)列里加入一個(gè)異步任務(wù)从铲,所以2什么時(shí)候執(zhí)行也是不確定的,在這里加了主線程休眠澄暮,所以2還是在結(jié)束之前執(zhí)行名段。

10.串行隊(duì)列里異步任務(wù)嵌套異步任務(wù)


串行隊(duì)列的特點(diǎn)導(dǎo)致就算是多個(gè)異步任務(wù)也只開啟一個(gè)線程,因?yàn)椴还荛_啟幾個(gè)都是順序執(zhí)行泣懊,開多了反而浪費(fèi)資源伸辟,就醬。

11.串行隊(duì)列里同步任務(wù)嵌套同步任務(wù)


這個(gè)組合就有意思馍刮,直接崩了信夫。這里需要好好分析一下,首先調(diào)用dispatch_sync函數(shù)將block添加到queue這個(gè)串行隊(duì)列的最后面卡啰,由于是同步任務(wù)静稻,所以會(huì)立刻執(zhí)行這個(gè)block,然后在這個(gè)block里面又調(diào)用一個(gè)dispatch_sync函數(shù)將另一個(gè)block添加到queue這個(gè)隊(duì)列的最后面匈辱,由于是同步任務(wù)振湾,所以會(huì)立刻執(zhí)行這個(gè)block,但這是一個(gè)串行隊(duì)列亡脸,要想執(zhí)行后面的blcok需要前面的dispatch_sync函數(shù)先返回押搪,但dispatch_sync函數(shù)要想返回需要執(zhí)行完這個(gè)block佛南,這就導(dǎo)致了兩個(gè)任務(wù)相互等待,造成死鎖嵌言。

12.延遲執(zhí)行

?dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0/*延遲執(zhí)行時(shí)間*/ * NSEC_PER_SEC));
???
??????????? dispatch_after(delayTime, dispatch_get_main_queue(), ^{
??????????????? NSLog(@"延遲執(zhí)行");
??????????? });

13.定時(shí)器


14.group之同步任務(wù)


通過(guò)group可以監(jiān)聽一組任務(wù)是否都完成,完成了會(huì)自動(dòng)回調(diào) dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^

? ? ? ? {

? ? ? ? ? ? // 完成

? ? ? ? ? ? NSLog(@"over");

? ? ? ? });

沒個(gè)任務(wù)都是在分線程中執(zhí)行的及穗,不占用主線程資源摧茴,適用于處理一下復(fù)雜的操作,當(dāng)所有任務(wù)結(jié)束之后埂陆,回調(diào)主線程刷新數(shù)據(jù)苛白。如果里面再添加異步任務(wù),這時(shí)候就失效了焚虱。

15.group之異步任務(wù)

上面說(shuō)了如果group里面又添加了異步任務(wù)购裙,那么上面的機(jī)制就不氣作用的,如果想要實(shí)現(xiàn)同樣的功能需要這樣做


加一對(duì)dispatch_group_enter(group)鹃栽,dispatch_group_leave(group);這樣就可以了躏率。

16.apply

如果我們寫一個(gè)for循環(huán)


結(jié)束是先執(zhí)行的,如果我們想要for循環(huán)執(zhí)行完之后再執(zhí)行結(jié)束民鼓,那可以這樣做


17.barrier(柵欄)


柵欄的就像一個(gè)分割線薇芝,前面的任務(wù)執(zhí)行完才能執(zhí)行后面的任務(wù)。


18.信號(hào)量


信號(hào)量在多線程開發(fā)中被廣泛使用丰嘉,當(dāng)一個(gè)線程在進(jìn)入一段關(guān)鍵代碼之前夯到,線程必須獲取一個(gè)信號(hào)量,一旦該關(guān)鍵代碼段完成了饮亏,那么該線程必須釋放信號(hào)量耍贾。其它想進(jìn)入該關(guān)鍵代碼段的線程必須等待前面的線程釋放信號(hào)量。

? ? 信號(hào)量的具體做法是:當(dāng)信號(hào)計(jì)數(shù)大于0時(shí)路幸,每條進(jìn)來(lái)的線程使計(jì)數(shù)減1荐开,直到變?yōu)?,變?yōu)?后其他的線程將進(jìn)不來(lái)劝赔,處于等待狀態(tài)誓焦;執(zhí)行完任務(wù)的線程釋放信號(hào),使計(jì)數(shù)加1着帽,如此循環(huán)下去杂伟。


最后附上一張各種線程鎖的效率排行。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末仍翰,一起剝皮案震驚了整個(gè)濱河市赫粥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌予借,老刑警劉巖越平,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件频蛔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡秦叛,警方通過(guò)查閱死者的電腦和手機(jī)晦溪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)挣跋,“玉大人三圆,你說(shuō)我怎么就攤上這事”芘兀” “怎么了舟肉?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)查库。 經(jīng)常有香客問(wèn)我路媚,道長(zhǎng),這世上最難降的妖魔是什么樊销? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任整慎,我火速辦了婚禮,結(jié)果婚禮上围苫,老公的妹妹穿的比我還像新娘院领。我一直安慰自己,他們只是感情好够吩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布比然。 她就那樣靜靜地躺著,像睡著了一般周循。 火紅的嫁衣襯著肌膚如雪强法。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天湾笛,我揣著相機(jī)與錄音饮怯,去河邊找鬼。 笑死嚎研,一個(gè)胖子當(dāng)著我的面吹牛蓖墅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播临扮,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼论矾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了杆勇?” 一聲冷哼從身側(cè)響起贪壳,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚜退,沒想到半個(gè)月后闰靴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體彪笼,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年蚂且,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了配猫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杏死,死狀恐怖章姓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情识埋,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布零渐,位于F島的核電站窒舟,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏诵盼。R本人自食惡果不足惜惠豺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望风宁。 院中可真熱鬧洁墙,春花似錦、人聲如沸戒财。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饮寞。三九已至孝扛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間幽崩,已是汗流浹背苦始。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慌申,地道東北人陌选。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蹄溉,于是被迫代替她去往敵國(guó)和親咨油。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353