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)),低,后臺(tái)四個(gè)優(yōu)先級(jí)別
dispatch_get_global_queue() 可以設(shè)置優(yōu)先級(jí)
  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ì)列級(jí)別,一般不做修改
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");

控制臺(tái)輸出如下: 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");

控制臺(tái)輸出信息: 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");

控制臺(tái)輸出:
current task -> next task -> 高優(yōu)先級(jí) -> 次優(yōu)先級(jí)
異步線程的執(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)識(shí) DISPATCH_QUEUE_SERIAL 隊(duì)列類型,串行或者并發(fā)
NSLog(@"%s", dispatch_queue_get_label(conCurrentQueue));
1.2 控制臺(tái)輸出
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 控制臺(tái)輸出

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 控制臺(tái)輸出如下

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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容