iOS GCD中的三種隊(duì)列類型

GCD中的三種隊(duì)列類型

GCD編程的核心就是dispatch隊(duì)列,dispatch block的執(zhí)行最終都會(huì)放進(jìn)某個(gè)隊(duì)列中去進(jìn)行.

  1. The main queue (主線程串行隊(duì)列):與主線程功能相同,提交到main queue的任務(wù)會(huì)在主線程中執(zhí)行
dispatch_get_main_queue() 來獲取
  1. Global queue (全局并發(fā)隊(duì)列):全局并發(fā)隊(duì)列由整個(gè)進(jìn)程共享,有高,中(默認(rèn)),低,后臺四個(gè)優(yōu)先級別
dispatch_get_global_queue() 可以設(shè)置優(yōu)先級
  1. Custom queue(自定義隊(duì)列) 可以串行,也可以并發(fā)
dispatch_queue_create()

Group queue(隊(duì)列組): 將多線程進(jìn)行分組,最大的好處是可獲知所有線程的完成情況
可以通過dispatch_group_create()來獲取,通過dispatch_group_notify,可以直接監(jiān)聽組里所有線程的完成情況.

GCD中相關(guān)函數(shù)的使用一般都是以dispatch開頭

The Main Queue 主線程串行隊(duì)列

dispatch_sync同步執(zhí)行任務(wù)函數(shù)不會(huì)開啟新的線程
dispatch_async異步執(zhí)行任務(wù),會(huì)開啟新的線程

1.獲取主線程串行隊(duì)列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
2.主線程串行隊(duì)列同步執(zhí)行任務(wù),在主線程運(yùn)行時(shí),會(huì)產(chǎn)生死鎖
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_sync (mainQueue, ^{
  NSLog(@"Main Queue");
});
程序一直處在等待狀態(tài),block中的代碼將執(zhí)行不到
3.主線程串行隊(duì)列異步執(zhí)行任務(wù),在主線程中運(yùn)行,不會(huì)產(chǎn)生死鎖.
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
  NSLog(@"Main Queue");
});
 程序正常運(yùn)行block中的代碼正常運(yùn)行
4.從子線程異步返回主線程更新UI
dispatch_queue_t globalQueue = dispath_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalQueue, ^{
  NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
  NSError *error;  //子線程異步執(zhí)行下載操作,防止主線程卡頓
  NSString *htmlDate = [NSString stringWithContentOfURL:url encoding: NSUTF8StringEncoding error:&error];
  if (htmlDate != nil){
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_async(mainQueue, ^{
    //異步返回主線程,根據(jù)獲取的數(shù)據(jù),更新UI
    });
  }else{
    NSLog(@"error when download: %@", error);
  }
});

主線程串行隊(duì)列由系統(tǒng)默認(rèn)生產(chǎn),無法調(diào)用dispatch_resume()和dispatch_suspend()來執(zhí)行繼續(xù)和中斷

Global Queue 全局并發(fā)隊(duì)列

耗時(shí)的操作,比如讀取網(wǎng)絡(luò)數(shù)據(jù),IO數(shù)據(jù)庫讀寫等,我們會(huì)在另一個(gè)線程中處理這些操作,然后通過主線程更新界面

1.獲取全局并發(fā)隊(duì)列
dispatch_queue_t globalQueue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //默認(rèn)隊(duì)列級別,一般不做修改
dispatch_queue_t globalQueue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t globalQueue3 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0);
dispatch_queue_t globalQueue4 = dispatch_get_global_queue(DISPATCH_QUEUE_BACKGROUND, 0);
2.全局并發(fā)隊(duì)列同步執(zhí)行任務(wù),在主線程中執(zhí)行會(huì)導(dǎo)致頁面卡頓
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"current task");
dispatch_sync(globalQueue, ^{
  sleep(2.0);
  NSLog(@"sleep 2.0s");
});
NSLog(@"next task");

控制臺輸出如下: current task -> sleep 2.0s -> next task
2s 鐘之后,才會(huì)執(zhí)行block代碼段下面的代碼

3.全局并發(fā)隊(duì)列異步執(zhí)行任務(wù),在主線程運(yùn)行,會(huì)開啟新的子線程去執(zhí)行任務(wù),頁面不會(huì)卡頓.
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"current task");
dispatch_async(globalQueue, ^{
  sleep(2.0);
  NSLog(@"sleep 2.0");
});
NSLog(@"next task");

控制臺輸出信息: current task -> next task -> sleep 2.0s
主線程不用等待2s鐘,繼續(xù)執(zhí)行block代碼段后面的代碼

4.多個(gè)全局并發(fā)隊(duì)列,異步執(zhí)行任務(wù).
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"current task");
dispatch_async(globalQueue, ^{
  NSLog(@"最先加入全局并發(fā)隊(duì)列");
});
dispatch_async(globalQueue, ^{
  NSLog(@"次加入全局并發(fā)隊(duì)列");
});
NSLog(@"next task");

控制臺輸出:
current task -> next task -> 高優(yōu)先級 -> 次優(yōu)先級
異步線程的執(zhí)行順序是不確定的,幾乎同步開始執(zhí)行
全局并發(fā)隊(duì)列由系統(tǒng)默認(rèn)生成的,所以無法調(diào)用dispatch_resum()和dispatch_suspend來控制執(zhí)行繼續(xù)和中斷

Custom Queue 自定義隊(duì)列

1. 自定義串行隊(duì)列
1.1 獲取自定義串行隊(duì)列
dispatch_queue_t serialQueue = dispatch_queue_create("com.dullgrass.serialQueue", DISPATCH_QUEUE_SERIAL);  // com.dullgrass.serialQueue 是給queue起的標(biāo)識 DISPATCH_QUEUE_SERIAL 隊(duì)列類型,串行或者并發(fā)
NSLog(@"%s", dispatch_queue_get_label(conCurrentQueue));
1.2 控制臺輸出
com.dullgrass.serialQueue
1.3 自定義串行隊(duì)列同步執(zhí)行任務(wù)
dispatch_queue_t serialQueue = dispatch_queue_create("com.dullgrass.serialQueue", DISPATCH_QUEUE_SERIAL);
NSLog(@"current task");
dispatch_sync(serialQueue, ^{
  NSLog(@"最先加入自定義串行隊(duì)列");
  sleep(2.0);
});
dispatch_sync(serialQueue, ^{
  NSLog(@"次加入自定義串行隊(duì)列");
});
NSLog(@"next task");
1.4 控制臺輸出

current task -> 最優(yōu) -> 次 -> next task
當(dāng)前線程等待串行隊(duì)列中的子線程執(zhí)行完成之后再執(zhí)行
串行隊(duì)列中先進(jìn)入子線程的隊(duì)列,執(zhí)行完成以后再執(zhí)行隊(duì)列中后面的任務(wù).

1.5 自定義串行隊(duì)列嵌套執(zhí)行同步任務(wù),產(chǎn)生死鎖
dispatch_queue_t serialQueue = dispatch_queue_create("com.dullgrass.serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(serialQueue, ^{
  //該代碼段后面的代碼不會(huì)執(zhí)行,程序被鎖死
  NSLog(@"會(huì)執(zhí)行的代碼");
  dispatch_sync(serialQueue, ^{
    NSLog(@"代碼不執(zhí)行"); 
  });
});
1.6 異步執(zhí)行串行隊(duì)列嵌套同步執(zhí)行串行隊(duì)列中的任務(wù),將不會(huì)被執(zhí)行,其他程序正常執(zhí)行
dispatch_queue_t serialQueue = dispatch_queue_create("com.dullgrass.serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
  NSLog(@"會(huì)執(zhí)行的代碼");
  dispatch_sync(serialQueue, ^{
    NSLog(@"代碼不會(huì)執(zhí)行");
  })
});

注意??: 不要嵌套使用同步執(zhí)行的串行隊(duì)列任務(wù)

2. 自定義并發(fā)隊(duì)列
2.1 獲取自定義并發(fā)隊(duì)列
dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.dullgrass.conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);
2.2 自定義并發(fā)隊(duì)列執(zhí)行同步任務(wù)
dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.dullgrass.conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"current task");
dispatch_sync(conCurrentQueue, ^{
  NSLog(@"先加入隊(duì)列");
});
dispatch_sync(conCurrentQueue, ^{
  NSLog(@"次加入隊(duì)列");
});
NSLog(@"next task");
2.3 控制臺輸出如下

current task -> 先 -> 次 -> next task

2.4 自定義并發(fā)隊(duì)列嵌套執(zhí)行同步任務(wù)(不會(huì)產(chǎn)生死鎖,程序正常運(yùn)行)
dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.dullgrass.conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"current task");
dispatch_sync(conCurrentQueue, ^{
  NSLog(@"先加入隊(duì)列");
  dispatch_sync(conCurrentQueue, ^{
    NSLog(@"次加入隊(duì)列");
  });
 });
NSLog(@"next task");

輸出:
current task -> 先加入隊(duì)列 -> 次加入隊(duì)列 -> next task

2.5 自定義并發(fā)隊(duì)列執(zhí)行異步任務(wù)
dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.dullgrass.conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"current task");
dispatch_async(conCurrentQueue, ^{
  NSLog(@"先加入隊(duì)列");
});
dispatch_async(conCurrentQueue, ^{
  NSLog(@"次加入隊(duì)列");
});
NSLog(@"next task");

輸出:
current task -> next task -> 次 -> 先
異步執(zhí)行任務(wù),開啟新的子線程,不影響當(dāng)前線程任務(wù)的執(zhí)行,并行隊(duì)列中的任務(wù),幾乎是同步執(zhí)行的,輸出順序不確定

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末捂龄,一起剝皮案震驚了整個(gè)濱河市倦沧,隨后出現(xiàn)的幾起案子它匕,更是在濱河造成了極大的恐慌豫柬,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喝噪,死亡現(xiàn)場離奇詭異指么,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翁涤,“玉大人葵礼,你說我怎么就攤上這事∪咏В” “怎么了届谈?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵艰山,是天一觀的道長曙搬。 經(jīng)常有香客問我,道長纵装,這世上最難降的妖魔是什么搂擦? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任扳还,我火速辦了婚禮,結(jié)果婚禮上氨距,老公的妹妹穿的比我還像新娘。我一直安慰自己楞遏,他們只是感情好寡喝,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布预鬓。 她就那樣靜靜地躺著格二,像睡著了一般顶猜。 火紅的嫁衣襯著肌膚如雪痘括。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機(jī)與錄音驰后,去河邊找鬼灶芝。 笑死郑原,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的夜涕。 我是一名探鬼主播犯犁,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼女器!你這毒婦竟也來了酸役?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涣澡,沒想到半個(gè)月后贱呐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡入桂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年奄薇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抗愁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出志于,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站惩妇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜股淡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一躲因、第九天 我趴在偏房一處隱蔽的房頂上張望搞监。 院中可真熱鬧秤标,春花似錦牢酵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琅束。三九已至,卻和暖如春艾船,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阻肩。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工柒室, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纺讲,地道東北人逢渔。 一個(gè)月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親呻澜。 傳聞我的和親對象是個(gè)殘疾皇子辫愉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

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