iOS 多線程GCD的基本使用

首先,我們先來看一下GCD 的簡單介紹.

GCD是 Apple 開發(fā)的一個(gè)多核編程的解決方法斩祭,簡單易用,效率高粘衬,速度快。通過 GCD咳促,開發(fā)者只需要向隊(duì)列中添加一段代碼塊(block或C函數(shù)指針)稚新,而不需要直接和線程打交道。GCD在后端管理著一個(gè)線程池跪腹,它不僅決定著你的代碼塊將在哪個(gè)線程被執(zhí)行褂删,還根據(jù)可用的系統(tǒng)資源對(duì)這些線程進(jìn)行管理。這樣通過GCD來管理線程尺迂,從而解決線程被創(chuàng)建的問題笤妙。

學(xué)習(xí)GCD 之前适刀,先來了解 GCD 中兩個(gè)核心概念:任務(wù)和隊(duì)列世蔗。

任務(wù):就是執(zhí)行操作的意思,換句話說就是你在線程中執(zhí)行的那段代碼暑认。在 GCD 中是放在 block 中的膳音。

執(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ù)惭适,具備開啟新線程的能力笙瑟。

隊(duì)列(Dispatch Queue):這里的隊(duì)列指執(zhí)行任務(wù)的等待隊(duì)列,即用來存放任務(wù)的隊(duì)列癞志。隊(duì)列是一種特殊的線性表往枷,采用 FIFO(先進(jìn)先出)的原則,即新任務(wù)總是被插入到隊(duì)列的末尾凄杯,而讀取任務(wù)的時(shí)候總是從隊(duì)列的頭部開始讀取错洁。每讀取一個(gè)任務(wù),則從隊(duì)列中釋放一個(gè)任務(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ù))

下面有代碼具體演示執(zhí)行方式與隊(duì)列結(jié)合使用的時(shí)候,各種情況的區(qū)別.

1.串行隊(duì)列 同步執(zhí)行

    NSLog(@"開始了");
    dispatch_queue_t serQueue = dispatch_queue_create("feng", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(serQueue, ^{
        for (int i = 0; i<10; i++) {
            NSLog(@"1111-%d --- %@", i, [NSThread currentThread]);
        }
    });
    dispatch_sync(serQueue, ^{
        for (int i = 0; i<10; i++) {
            NSLog(@"2222-%d --- %@", i, [NSThread currentThread]);
        }
    });
    NSLog(@"結(jié)束了");
image.png

如上圖所示,任務(wù)一加入就開始執(zhí)行, 并且按照順序執(zhí)行, 不開辟線程.

2.串行隊(duì)列 異步執(zhí)行

    NSLog(@"開始了");
    dispatch_queue_t serQueue = dispatch_queue_create("feng", DISPATCH_QUEUE_SERIAL);
    dispatch_async(serQueue, ^{
        for (int i = 0; i<10; i++) {
            NSLog(@"1111-%d --- %@", i, [NSThread currentThread]);
        }
    });
    dispatch_async(serQueue, ^{
        for (int i = 0; i<10; i++) {
            NSLog(@"2222-%d --- %@", i, [NSThread currentThread]);
        }
    });
    NSLog(@"結(jié)束了");
image.png

如上圖所示,任務(wù)全部加入才開始執(zhí)行, 按照順序執(zhí)行, 開辟線程.

3.并行隊(duì)列 同步執(zhí)行

    NSLog(@"開始了");
    dispatch_queue_t serQueue = dispatch_queue_create("feng", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(serQueue, ^{
        for (int i = 0; i<10; i++) {
            NSLog(@"1111-%d --- %@", i, [NSThread currentThread]);
        }
    });
    dispatch_sync(serQueue, ^{
        for (int i = 0; i<10; i++) {
            NSLog(@"2222-%d --- %@", i, [NSThread currentThread]);
        }
    });
    NSLog(@"結(jié)束了");
image.png

如上圖所示,任務(wù)一加入就開始執(zhí)行, 按照順序執(zhí)行, 不開辟線程.

4.并行隊(duì)列 異步執(zhí)行

NSLog(@"開始了");
    dispatch_queue_t serQueue = dispatch_queue_create("feng", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(serQueue, ^{
        for (int i = 0; i<10; i++) {
            NSLog(@"1111-%d --- %@", i, [NSThread currentThread]);
        }
        for (int i = 0; i<10; i++) {
            NSLog(@"2222-%d --- %@", i, [NSThread currentThread]);
        }
    });
    dispatch_async(serQueue, ^{
        for (int i = 0; i<10; i++) {
            NSLog(@"3333-%d --- %@", i, [NSThread currentThread]);
        }
        for (int i = 0; i<10; i++) {
            NSLog(@"4444-%d --- %@", i, [NSThread currentThread]);
        }
    });
    NSLog(@"結(jié)束了");
image.png

如上圖所示,任務(wù)全部加入才開始執(zhí)行, 并發(fā)執(zhí)行, 開辟線程.

總結(jié):

1.同步(dispatch_sync) 任務(wù)一進(jìn)入任務(wù)就直接開始執(zhí)行. 不開辟線程.
2.異步(dispatch_async) 所有的任務(wù)都進(jìn)入了,才開始執(zhí)行,會(huì)開辟線程.

追加的其他功能:

柵欄函數(shù)dispatch_barrier_async的使用

// 1.創(chuàng)建并發(fā)隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    // 2.向隊(duì)列中添加任務(wù)
    dispatch_async(queue, ^{  // 1.2是并行的
        NSLog(@"任務(wù)1, %@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)2, %@",[NSThread currentThread]);
    });
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"任務(wù) barrier, %@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{   // 這兩個(gè)是同時(shí)執(zhí)行的
        NSLog(@"任務(wù)3, %@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)4, %@",[NSThread currentThread]);
    });
image.png

如上圖所示,注意: 輸出結(jié)果: 任務(wù)1 任務(wù)2 ——》 任務(wù) barrier ——》任務(wù)3 任務(wù)4
// 其中的任務(wù)1與任務(wù)2埂息,任務(wù)3與任務(wù)4 由于是并行處理先后順序不定技潘。

本項(xiàng)目源碼: GCD演示Demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市千康,隨后出現(xiàn)的幾起案子享幽,更是在濱河造成了極大的恐慌,老刑警劉巖拾弃,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件值桩,死亡現(xiàn)場離奇詭異,居然都是意外死亡豪椿,警方通過查閱死者的電腦和手機(jī)奔坟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門携栋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人咳秉,你說我怎么就攤上這事婉支。” “怎么了澜建?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵磅摹,是天一觀的道長。 經(jīng)常有香客問我霎奢,道長户誓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任幕侠,我火速辦了婚禮帝美,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘晤硕。我一直安慰自己悼潭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布舞箍。 她就那樣靜靜地躺著舰褪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疏橄。 梳的紋絲不亂的頭發(fā)上占拍,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音捎迫,去河邊找鬼晃酒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛窄绒,可吹牛的內(nèi)容都是我干的贝次。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼彰导,長吁一口氣:“原來是場噩夢啊……” “哼蛔翅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起位谋,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤山析,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后倔幼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盖腿,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翩腐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸟款。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖茂卦,靈堂內(nèi)的尸體忽然破棺而出何什,到底是詐尸還是另有隱情,我是刑警寧澤等龙,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布处渣,位于F島的核電站,受9級(jí)特大地震影響蛛砰,放射性物質(zhì)發(fā)生泄漏罐栈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一泥畅、第九天 我趴在偏房一處隱蔽的房頂上張望荠诬。 院中可真熱鬧,春花似錦位仁、人聲如沸柑贞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钧嘶。三九已至,卻和暖如春琳疏,著一層夾襖步出監(jiān)牢的瞬間有决,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國打工轿亮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疮薇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓我注,卻偏偏與公主長得像,于是被迫代替她去往敵國和親迟隅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子但骨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容