GCD 的理解

1. GCD 的兩個(gè)核心 :任務(wù) 和 隊(duì)列

任務(wù):就是執(zhí)行操作的意思脖捻,換句話(huà)說(shuō)就是你在線程中執(zhí)行的那段代碼佩耳。在 GCD 中是放在 block 中的享言。執(zhí)行任務(wù)有兩種方式:同步執(zhí)行(sync)和異步執(zhí)行(async)。兩者的主要區(qū)別是:是否等待隊(duì)列的任務(wù)執(zhí)行結(jié)束,以及是否具備開(kāi)啟新線程的能力册着。

  • 同步執(zhí)行(sync):

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

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

隊(duì)列(Dispatch Queue):這里的隊(duì)列指執(zhí)行任務(wù)的等待隊(duì)列钦奋,即用來(lái)存放任務(wù)的隊(duì)列。隊(duì)列是一種特殊的線性表,采用 FIFO(先進(jìn)先出)的原則付材,即新任務(wù)總是被插入到隊(duì)列的末尾朦拖,而讀取任務(wù)的時(shí)候總是從隊(duì)列的頭部開(kāi)始讀取。每讀取一個(gè)任務(wù)厌衔,則從隊(duì)列中釋放一個(gè)任務(wù)璧帝。

  • 串行隊(duì)列(Serial Dispatch Queue):每次只有一個(gè)任務(wù)被執(zhí)行。讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行富寿。只開(kāi)啟一個(gè)線程睬隶,一個(gè)任務(wù)執(zhí)行完畢后,再執(zhí)行下一個(gè)任務(wù)
  • 并行隊(duì)列(Concurrent Dispatch Queue):可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行页徐。可以開(kāi)啟多個(gè)線程理疙,并且同時(shí)執(zhí)行任務(wù)

個(gè)人理解: 隊(duì)列(Serial和Concurrent) 決定是否 具備 開(kāi)啟線程的能力,sync和async決定是否 開(kāi)啟 另外的線程

開(kāi)啟線程的能力跟所在的線程沒(méi)關(guān)系

截屏2020-11-19下午8.19.36.png

2. 代碼解析

代碼1
//創(chuàng)建串行隊(duì)列
    dispatch_queue_t mySerialQueue = dispatch_queue_create("my_test_queue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t myQueue = dispatch_queue_create("my_test_queue_2", DISPATCH_QUEUE_SERIAL);

    //異步執(zhí)行+串行隊(duì)列:開(kāi)啟一個(gè)線程
    dispatch_async(mySerialQueue, ^{
        //任務(wù)1
        NSLog(@"7-----%@",[NSThread currentThread]);
        NSLog(@"7 === start");
        //異步 不用等待 繼續(xù)執(zhí)行
        dispatch_async(myQueue, ^{
             //任務(wù)3
            NSLog(@"4 === start");
            for (int i = 0; i<2; i++) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"4-----%@",[NSThread currentThread]);
            }
            dispatch_async(mySerialQueue, ^{
                 //任務(wù)4
                NSLog(@"8 === start");
                for (int i = 0; i<2; i++) {
                    [NSThread sleepForTimeInterval:2];
                    NSLog(@"8-----%@",[NSThread currentThread]);
                }
                NSLog(@"8 === end");
            });
            NSLog(@"4 === end");
        });
        //異步 不用等待繼續(xù)執(zhí)行
        dispatch_async(myQueue, ^{
            //任務(wù)5
            NSLog(@"5 === start");
            for (int i = 0; i<2; i++) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"5-----%@",[NSThread currentThread]);
            }
        });
        NSLog(@"7 === end");
    });
    //串行隊(duì)列 需一個(gè)一個(gè)執(zhí)行 :等待 NSLog(@"7 === end") 執(zhí)行后再執(zhí)行
    dispatch_async(mySerialQueue, ^{
        //任務(wù)2
        NSLog(@"9 === start");
        for (int i = 0; i<2; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"9-----%@",[NSThread currentThread]);
        }
        NSLog(@"9 === end");
    });

執(zhí)行后輸出結(jié)果是 :

2019-04-16 14:37:09.149808+0800 test123[95964:8582595] 7-----<NSThread: 0x6000020ea7c0>{number = 3, name = (null)}
2019-04-16 14:37:09.149973+0800 test123[95964:8582595] 7 === start
2019-04-16 14:37:09.150092+0800 test123[95964:8582595] 7 === end
2019-04-16 14:37:09.150102+0800 test123[95964:8582592] 4 === start
2019-04-16 14:37:09.150225+0800 test123[95964:8582595] 9 === start
2019-04-16 14:37:11.153315+0800 test123[95964:8582595] 9-----<NSThread: 0x6000020ea7c0>{number = 3, name = (null)}
2019-04-16 14:37:11.153338+0800 test123[95964:8582592] 4-----<NSThread: 0x6000020e3040>{number = 4, name = (null)}
2019-04-16 14:37:13.157628+0800 test123[95964:8582595] 9-----<NSThread: 0x6000020ea7c0>{number = 3, name = (null)}
2019-04-16 14:37:13.157649+0800 test123[95964:8582592] 4-----<NSThread: 0x6000020e3040>{number = 4, name = (null)}
2019-04-16 14:37:13.158006+0800 test123[95964:8582595] 9 === end
2019-04-16 14:37:13.158021+0800 test123[95964:8582592] 4 === end
2019-04-16 14:37:13.158315+0800 test123[95964:8582592] 5 === start
2019-04-16 14:37:13.158366+0800 test123[95964:8582595] 8 === start
2019-04-16 14:37:15.163083+0800 test123[95964:8582592] 5-----<NSThread: 0x6000020e3040>{number = 4, name = (null)}
2019-04-16 14:37:15.163111+0800 test123[95964:8582595] 8-----<NSThread: 0x6000020ea7c0>{number = 3, name = (null)}
2019-04-16 14:37:17.163967+0800 test123[95964:8582592] 5-----<NSThread: 0x6000020e3040>{number = 4, name = (null)}
2019-04-16 14:37:17.163967+0800 test123[95964:8582595] 8-----<NSThread: 0x6000020ea7c0>{number = 3, name = (null)}
2019-04-16 14:37:17.164365+0800 test123[95964:8582595] 8 === end

分析:任務(wù)3(4===start) 比 任務(wù)2(9===start) 早輸出原因:異步執(zhí)行 任務(wù)3 后泞坦,下邊代碼還有耗時(shí)操作(任務(wù)5窖贤、NSLog)所以 任務(wù)2 需要等待,會(huì)先異步執(zhí)行 任務(wù)3(4 === start )

代碼2
dispatch_group_t group = dispatch_group_create();

    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"1 === start");
        for (int i = 0; i<2; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"1-----%@",[NSThread currentThread]);
        }
        NSLog(@"1 === end");
    });
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"2 === start");
        for (int i = 0; i<2; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2-----%@",[NSThread currentThread]);
        }
        NSLog(@"2 === end");
        dispatch_group_leave(group);
    });
    dispatch_group_enter(group);
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t mySerialQueue = dispatch_queue_create("my_test_queue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t myQueue = dispatch_queue_create("my_test_queue_2", DISPATCH_QUEUE_SERIAL);

    //異步執(zhí)行+串行隊(duì)列:開(kāi)啟一個(gè)線程
    dispatch_async(mySerialQueue, ^{
        NSLog(@"7-----%@",[NSThread currentThread]);
        NSLog(@"7 === start");
        //異步 不用等待 繼續(xù)執(zhí)行
        dispatch_async(myQueue, ^{
            NSLog(@"4 === start");
            for (int i = 0; i<2; i++) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"4-----%@",[NSThread currentThread]);
            }
            dispatch_async(mySerialQueue, ^{
                NSLog(@"8 === start");
                for (int i = 0; i<2; i++) {
                    [NSThread sleepForTimeInterval:2];
                    NSLog(@"8-----%@",[NSThread currentThread]);
                }
                NSLog(@"8 === end");
            });
            NSLog(@"4 === end");
        });
        //異步 不用等待繼續(xù)執(zhí)行
        dispatch_async(myQueue, ^{
            NSLog(@"5 === start");
            for (int i = 0; i<2; i++) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"5-----%@",[NSThread currentThread]);
            }
        });
        NSLog(@"7 === end");
    });
    //串行隊(duì)列 需一個(gè)一個(gè)執(zhí)行 :等待 NSLog(@"7 === end") 執(zhí)行后再執(zhí)行
    dispatch_async(mySerialQueue, ^{
        NSLog(@"9 === start");
        for (int i = 0; i<2; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"9-----%@",[NSThread currentThread]);
        }
        NSLog(@"9 === end");
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"3 === start");
        for (int i = 0; i<2; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3-----%@",[NSThread currentThread]);
        }
    });

輸出結(jié)果:

2019-04-16 14:49:41.670736+0800 test123[96172:8588712] 7-----<NSThread: 0x600003583cc0>{number = 3, name = (null)}
2019-04-16 14:49:41.670807+0800 test123[96172:8588710] 1 === start
2019-04-16 14:49:41.670865+0800 test123[96172:8588711] 2 === start
2019-04-16 14:49:41.670975+0800 test123[96172:8588712] 7 === start
2019-04-16 14:49:41.671074+0800 test123[96172:8588712] 7 === end
2019-04-16 14:49:41.671086+0800 test123[96172:8588709] 4 === start
2019-04-16 14:49:41.671177+0800 test123[96172:8588712] 9 === start
2019-04-16 14:49:43.675862+0800 test123[96172:8588710] 1-----<NSThread: 0x600003597380>{number = 4, name = (null)}
2019-04-16 14:49:43.675871+0800 test123[96172:8588712] 9-----<NSThread: 0x600003583cc0>{number = 3, name = (null)}
2019-04-16 14:49:43.675862+0800 test123[96172:8588711] 2-----<NSThread: 0x60000358af40>{number = 5, name = (null)}
2019-04-16 14:49:43.675864+0800 test123[96172:8588709] 4-----<NSThread: 0x60000358adc0>{number = 6, name = (null)}
2019-04-16 14:49:45.680467+0800 test123[96172:8588711] 2-----<NSThread: 0x60000358af40>{number = 5, name = (null)}
2019-04-16 14:49:45.680547+0800 test123[96172:8588712] 9-----<NSThread: 0x600003583cc0>{number = 3, name = (null)}
2019-04-16 14:49:45.680467+0800 test123[96172:8588710] 1-----<NSThread: 0x600003597380>{number = 4, name = (null)}
2019-04-16 14:49:45.680478+0800 test123[96172:8588709] 4-----<NSThread: 0x60000358adc0>{number = 6, name = (null)}
2019-04-16 14:49:45.680875+0800 test123[96172:8588711] 2 === end
2019-04-16 14:49:45.680874+0800 test123[96172:8588712] 9 === end
2019-04-16 14:49:45.680967+0800 test123[96172:8588709] 4 === end
2019-04-16 14:49:45.680874+0800 test123[96172:8588710] 1 === end
2019-04-16 14:49:45.681135+0800 test123[96172:8588712] 8 === start
2019-04-16 14:49:45.681224+0800 test123[96172:8588709] 5 === start
2019-04-16 14:49:45.681723+0800 test123[96172:8588662] 3 === start
2019-04-16 14:49:47.682394+0800 test123[96172:8588662] 3-----<NSThread: 0x6000035e2940>{number = 1, name = main}
2019-04-16 14:49:47.683973+0800 test123[96172:8588709] 5-----<NSThread: 0x60000358adc0>{number = 6, name = (null)}
2019-04-16 14:49:47.684043+0800 test123[96172:8588712] 8-----<NSThread: 0x600003583cc0>{number = 3, name = (null)}
2019-04-16 14:49:49.683874+0800 test123[96172:8588662] 3-----<NSThread: 0x6000035e2940>{number = 1, name = main}
2019-04-16 14:49:49.684750+0800 test123[96172:8588709] 5-----<NSThread: 0x60000358adc0>{number = 6, name = (null)}
2019-04-16 14:49:49.684799+0800 test123[96172:8588712] 8-----<NSThread: 0x600003583cc0>{number = 3, name = (null)}
2019-04-16 14:49:49.685113+0800 test123[96172:8588712] 8 === end

解析:1和2先后順序不一定 1贰锁、2赃梧、4、9相互交替執(zhí)行豌熄,5肯定在4結(jié)束后執(zhí)行授嘀,8肯定在9執(zhí)行完后執(zhí)行,最后5和8交替執(zhí)行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末锣险,一起剝皮案震驚了整個(gè)濱河市蹄皱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌芯肤,老刑警劉巖巷折,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異崖咨,居然都是意外死亡锻拘,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)击蹲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)署拟,“玉大人,你說(shuō)我怎么就攤上這事歌豺⊥魄睿” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵类咧,是天一觀的道長(zhǎng)馒铃。 經(jīng)常有香客問(wèn)我谴咸,道長(zhǎng),這世上最難降的妖魔是什么骗露? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任岭佳,我火速辦了婚禮,結(jié)果婚禮上萧锉,老公的妹妹穿的比我還像新娘珊随。我一直安慰自己,他們只是感情好柿隙,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布叶洞。 她就那樣靜靜地躺著,像睡著了一般禀崖。 火紅的嫁衣襯著肌膚如雪衩辟。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天波附,我揣著相機(jī)與錄音艺晴,去河邊找鬼。 笑死掸屡,一個(gè)胖子當(dāng)著我的面吹牛封寞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播仅财,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼狈究,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了盏求?” 一聲冷哼從身側(cè)響起抖锥,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碎罚,沒(méi)想到半個(gè)月后磅废,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡魂莫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年还蹲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耙考。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖潭兽,靈堂內(nèi)的尸體忽然破棺而出倦始,到底是詐尸還是另有隱情,我是刑警寧澤山卦,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布鞋邑,位于F島的核電站诵次,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏枚碗。R本人自食惡果不足惜逾一,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肮雨。 院中可真熱鬧遵堵,春花似錦、人聲如沸怨规。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)波丰。三九已至壳坪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掰烟,已是汗流浹背爽蝴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纫骑,地道東北人霜瘪。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像惧磺,于是被迫代替她去往敵國(guó)和親颖对。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

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