多線程(GCD)

  • 蘋果公司為多核的并行運(yùn)算提供的解決方案
  • 會(huì)自動(dòng)利用更多的CPU內(nèi)核
  • 會(huì)自動(dòng)管理線程的生命周期

幾個(gè)概念(同步 異步 串行 并行)

同步/異步關(guān)系到能否開啟新線程

  • 同步: 只是在當(dāng)前線程中執(zhí)行, 不具備開線程的能力
  • 異步: 可以在新的線程中執(zhí)行, 具備開線程的能力

串行/并行主要影響 任務(wù)的執(zhí)行方式

  • 并發(fā): 允許多個(gè)任務(wù)(并發(fā))同步執(zhí)行
  • 串行: 一個(gè)任務(wù)執(zhí)行完畢后, 再執(zhí)行另一個(gè)任務(wù)

基本使用

  • 異步函數(shù)+并發(fā)隊(duì)列 (會(huì)開啟多條線程, 隊(duì)列中任務(wù)并發(fā)執(zhí)行)
// 1.創(chuàng)建隊(duì)列
/*
   第一個(gè)參數(shù): C語言字符串 隊(duì)列標(biāo)簽區(qū)分不同隊(duì)列
   第二個(gè)參數(shù): 隊(duì)列類型
        DISPATCH_QUEUE_CONCURRENT: 并行隊(duì)列
        DISPATCH_QUEUE_SERIAL: 串行隊(duì)列
 */
dispatch_queue_t q = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT);
// 2.封裝任務(wù)
/*
 第一個(gè)參數(shù): 隊(duì)列
 第二個(gè)參數(shù): 代碼塊
 */
// 異步
dispatch_async(q, ^{
    // 執(zhí)行代碼
});
  • 異步函數(shù)+串行隊(duì)列 (會(huì)開啟線程, 隊(duì)列中任務(wù)前進(jìn)先出)
// 1.創(chuàng)建隊(duì)列
dispatch_queue_t q = dispatch_queue_create("", DISPATCH_QUEUE_SERIAL);
// 2.封裝任務(wù)
dispatch_async(q, ^{
    // 執(zhí)行代碼
});
  • 同步函數(shù)+并發(fā)隊(duì)列 (不會(huì)開啟線程, 任務(wù)串行執(zhí)行)
// 1.創(chuàng)建隊(duì)列
dispatch_queue_t q = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT);

// 2.封裝任務(wù)
dispatch_sync(q, ^{
    // 執(zhí)行代碼
});
  • 同步函數(shù)+串行隊(duì)列 (不會(huì)開啟線程, 任務(wù)串行執(zhí)行)
// 1.創(chuàng)建隊(duì)列
dispatch_queue_t q = dispatch_queue_create("", DISPATCH_QUEUE_SERIAL);

// 2.封裝任務(wù)
dispatch_sync(q, ^{
    // 執(zhí)行代碼
});
  • 異步函數(shù)+主隊(duì)列
// 1.創(chuàng)建隊(duì)列
dispatch_queue_t q = dispatch_get_main_queue();
// 2.封裝任務(wù)
dispatch_async(q, ^{
    // 執(zhí)行代碼
});
  • 同步函數(shù)+主隊(duì)列 (死鎖)
// 1.創(chuàng)建隊(duì)列
dispatch_queue_t q = dispatch_get_main_queue();
// 2.封裝任務(wù)
// 同步函數(shù): 如果我沒有執(zhí)行完, 后面不能執(zhí)行
dispatch_sync(q, ^{
    // 執(zhí)行代碼
    NSLog(@"download1------%@",[NSThread currentThread]);
});
dispatch_sync(q, ^{
    // 執(zhí)行代碼
    NSLog(@"download2------%@",[NSThread currentThread]);
});
dispatch_sync(q, ^{
    // 執(zhí)行代碼
    NSLog(@"download3------%@",[NSThread currentThread]);
});

線程間通訊

// 創(chuàng)建子線程
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    
    // 執(zhí)行任務(wù)
    /*
     ......
     */
    // 回主線程更新
    dispatch_async(dispatch_get_main_queue(), ^{
        // 更新UI
    });
    
});

GCD常用函數(shù)

// 延時(shí)
-(void)delay{
   // 常規(guī)方法一
   [self performSelector:@selector(task) withObject:nil afterDelay:2.0];
   // 常規(guī)方法二
   [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(task) userInfo:nil repeats:NO];
   // GCD方法 (可以控制執(zhí)行的線程)
   /*
    第一個(gè)參數(shù): DISPATCH_TIME_NOW 從現(xiàn)在開始計(jì)算時(shí)間
    第二個(gè)參數(shù): 延遲時(shí)間 GCD時(shí)間單位是納秒
    第三個(gè)參數(shù): 隊(duì)列
    */
   // dispatch_queue_t queue = dispatch_get_main_queue();
   dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), queue, ^{
    
});
}

// 一次性代碼
-(void)once{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    
    });
}

// 柵欄函數(shù)
-(void)zhalan
{
    // 1.創(chuàng)建隊(duì)列
//    dispatch_queue_t q = dispatch_get_global_queue(0, 0);
    dispatch_queue_t q = dispatch_queue_create("",     DISPATCH_QUEUE_CONCURRENT);
    // 2.封裝任務(wù)
    dispatch_async(q, ^{
        // 執(zhí)行代碼
        NSLog(@"download1------%@",[NSThread currentThread]);
    });

    // 柵欄函數(shù)不能使用全局并發(fā)隊(duì)列
    dispatch_barrier_async(q, ^{
           // 柵欄函數(shù)上面的任務(wù)先執(zhí)行, 下面的函數(shù)后執(zhí)行
    });

    dispatch_async(q, ^{
        // 執(zhí)行代碼
        NSLog(@"download2------%@",[NSThread currentThread]);
    });

    dispatch_async(q, ^{
       // 執(zhí)行代碼
        NSLog(@"download3------%@",[NSThread currentThread]);
    });
}

// 快速遍歷
-(void)apply
{
    /*
     第一個(gè)參數(shù): 遍歷次數(shù)
     第二個(gè)參數(shù): 隊(duì)列(必須是并發(fā)隊(duì)列)
     第三個(gè)參數(shù): 索引
     */
    dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t idx) {
        // 內(nèi)部開多個(gè)子線程和主線程一起完成任務(wù) 任務(wù)的執(zhí)行是并發(fā)的
    });
}

// 隊(duì)列組
-(void)queueGroup1
{
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_async(queue, ^{
        NSLog(@"1---------%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2---------%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3---------%@",[NSThread currentThread]);
    });

    // 需求: 三個(gè)任務(wù)都完成后執(zhí)行其他操作
    dispatch_group_async(group, queue, ^{
        NSLog(@"1---------%@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"2---------%@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"3---------%@",[NSThread currentThread]);
    });
    dispatch_group_notify(group, queue, ^{
        // 隊(duì)列組任務(wù)執(zhí)行完后 執(zhí)行此方法
    });

    // 死等 必須任務(wù)組中任務(wù)都執(zhí)行完畢才能執(zhí)行 阻塞的 (與dispatch_group_notify作用相同)
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
}

GCD補(bǔ)充知識(shí)點(diǎn)

-(void)supplement
{
    // block封裝
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
    });
 
    // 函數(shù)式封裝
    /*
     第一個(gè)參數(shù): 隊(duì)列
     第二個(gè)參數(shù): 參數(shù)
     第三個(gè)參數(shù): 要調(diào)用的函數(shù)名稱
     */
    dispatch_async_f(dispatch_get_global_queue(0, 0), NULL, task);
}

void task(void *param)
{
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尚氛,一起剝皮案震驚了整個(gè)濱河市闰靴,隨后出現(xiàn)的幾起案子蛙埂,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昂勒,死亡現(xiàn)場(chǎng)離奇詭異恬汁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)再芋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門菊霜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人济赎,你說我怎么就攤上這事鉴逞。” “怎么了司训?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵构捡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我壳猜,道長(zhǎng)勾徽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任统扳,我火速辦了婚禮喘帚,結(jié)果婚禮上畅姊,老公的妹妹穿的比我還像新娘。我一直安慰自己吹由,他們只是感情好若未,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著溉知,像睡著了一般陨瘩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上级乍,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天舌劳,我揣著相機(jī)與錄音,去河邊找鬼玫荣。 笑死甚淡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的捅厂。 我是一名探鬼主播贯卦,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼焙贷!你這毒婦竟也來了撵割?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤辙芍,失蹤者是張志新(化名)和其女友劉穎啡彬,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體故硅,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡庶灿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吃衅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片往踢。...
    茶點(diǎn)故事閱讀 38,654評(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,940評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妄帘。 院中可真熱鬧楞黄,春花似錦、人聲如沸抡驼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽致盟。三九已至碎税,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間馏锡,已是汗流浹背雷蹂。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杯道,地道東北人匪煌。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像党巾,于是被迫代替她去往敵國和親萎庭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

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

  • 目錄 一齿拂、基本概念1.多線程2.串行和并行驳规, 并發(fā)3.隊(duì)列與任務(wù)4.同步與異步5.線程狀態(tài)6.多線程方案 二、GC...
    BohrIsLay閱讀 1,573評(píng)論 5 12
  • 從哪說起呢署海? 單純講多線程編程真的不知道從哪下嘴达舒。。 不如我直接引用一個(gè)最簡(jiǎn)單的問題叹侄,以這個(gè)作為切入點(diǎn)好了 在ma...
    Mr_Baymax閱讀 2,739評(píng)論 1 17
  • 多線程學(xué)習(xí)筆記-GCD 我把這篇文章所用到的代碼總結(jié)到這里->GCD項(xiàng)目總結(jié)下載地址-GCD-wxk可以下載參考 ...
    wxkkkkk閱讀 531評(píng)論 0 2
  • 目錄:iOS多線程(一)--pthread、NSThreadiOS多線程(二)--GCD詳解iOS多線程(三)--...
    Claire_wu閱讀 1,066評(píng)論 0 6
  • 門外的清雨淅瀝的下個(gè)不停 那雨中奔跑的貨車還在呼呼地跑個(gè)不停 路上一片白 沒有風(fēng) 那雨中的生命給了沉悶的世界一絲安...
    劍倚天下閱讀 153評(píng)論 1 2