理解
串行隊(duì)列: 先入先出,執(zhí)行完第一個再執(zhí)行第二個淆储。
并發(fā)隊(duì)列: 先執(zhí)行第一個笋轨,第一個還沒執(zhí)行完時便可以執(zhí)行第二個秆剪。
并發(fā)是編程角度上的上同時,一個CPU也可以爵政,兩個任務(wù)交替進(jìn)行
并行是物理CPU上同時執(zhí)行(至少兩個CPU)
GCD中的同步和異步是針對任務(wù)的執(zhí)行來說的
同步:執(zhí)行完一個函數(shù)后在執(zhí)行下一個函數(shù),不會開啟新線程
異步:不管當(dāng)前函數(shù)仅讽,都會繼續(xù)執(zhí)行下一個函數(shù),開啟新線程
同步和異步的主要區(qū)別是向隊(duì)列里面添加任務(wù)時是立即返回還是等添加的任務(wù)完成之后再返回。
主要應(yīng)用場景:
- 串行隊(duì)列钾挟,同步任務(wù)(主線程中執(zhí)行洁灵,不開啟新線程,順序執(zhí)行)
- 串行隊(duì)列,異步任務(wù)(開啟一條新線程掺出,順序執(zhí)行处渣,需要在主線程刷新ui)
- 并發(fā)隊(duì)列,同步任務(wù)(不開啟新線程蛛砰,順序執(zhí)行)
- 并發(fā)隊(duì)列罐栈,異步任務(wù)(開啟多條線程,無順序執(zhí)行泥畅,需要在主線程刷新ui)
- 全局任務(wù)/并發(fā)隊(duì)列
- 延遲執(zhí)行任務(wù) (dispatch_after)
- 一次執(zhí)行任務(wù) (dispatch_once)
- 調(diào)度組 (用一個調(diào)度組荠诬,可以監(jiān)聽全局隊(duì)列的任務(wù))
- 主隊(duì)列異步任務(wù)
- 主隊(duì)列同步任務(wù)(死鎖)
- 主隊(duì)列同步任務(wù)(不死鎖)
串行隊(duì)列,同步任務(wù)
//創(chuàng)建串行任務(wù)
dispatch_queue_t queue = dispatch_queue_create("串行隊(duì)列", DISPATCH_QUEUE_SERIAL);
//執(zhí)行同步任務(wù)
for(int i = 0; i < 10; ++i){
dispatch_sync(queue, ^{
NSString *str = [NSString stringWithFormat:@"線程=%@ 角標(biāo):%d",[NSThread currentThread],i];
});
}
//主線程中執(zhí)行位仁,不開啟新線程,順序執(zhí)行
串行隊(duì)列柑贞,異步任務(wù)
dispatch_queue_t q = dispatch_queue_create("串行隊(duì)列", DISPATCH_QUEUE_SERIAL);
for (int i = 0; i < 10; i++) {
//在主線程中刷新UI
dispatch_async(q, ^{
NSString *str = [NSString stringWithFormat:@"線程=%@ 角標(biāo):%d",[NSThread currentThread],i];
NSLog(@"%@",str);
});
}
//開啟一條新線程,順序執(zhí)行
并發(fā)隊(duì)列聂抢,同步任務(wù)
dispatch_queue_t q = dispatch_queue_create("并發(fā)隊(duì)列", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 10; i++) {
dispatch_sync(q, ^{
NSString *str = [NSString stringWithFormat:@"線程=%@ 角標(biāo):%d",[NSThread currentThread],i];
NSLog(@"%@",str);
});
}
并發(fā)隊(duì)列钧嘶,異步任務(wù)
dispatch_queue_t q = dispatch_queue_create("并發(fā)隊(duì)列", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 10; i++) {
dispatch_async(q, ^{
//在主線程中刷新UI
NSString *str = [NSString stringWithFormat:@"線程=%@ 角標(biāo):%d",[NSThread currentThread],i];
NSLog(@"%@",str);
});
}
//開啟多條線程,無順序執(zhí)行
調(diào)度組
問題:iOS 有a琳疏、b有决、c、d 4個異步請求空盼,如何判斷a书幕、b、c揽趾、d都完成執(zhí)行台汇?
[答案:用調(diào)度組]
/*用一個 調(diào)度組 監(jiān)聽全局隊(duì)列的任務(wù)*/
//創(chuàng)建一個全局隊(duì)列
dispatch_queue_t q = dispatch_get_global_queue(0, 0);
//創(chuàng)建一個調(diào)度組
dispatch_group_t g = dispatch_group_create();
//添加任務(wù),讓隊(duì)列調(diào)度
dispatch_group_async(g, q, ^{
NSString *log = [NSString stringWithFormat:@"下載第一個文件%@", [NSThread currentThread]];
NSLog(@"%@",str);
});
dispatch_group_async(g, q, ^{
[NSThread sleepForTimeInterval:5];//延遲5秒
NSString *log = [NSString stringWithFormat:@"下載第二個文件%@", [NSThread currentThread]];
NSLog(@"%@",str);
});
dispatch_group_async(g, q, ^{
NSString *log = [NSString stringWithFormat:@"下載第三個文件%@", [NSThread currentThread]];
NSLog(@"%@",str);
});
//所有任務(wù)執(zhí)行完成后,通知調(diào)度組
dispatch_group_notify(g, dispatch_get_main_queue(), ^{
NSString *log = [NSString stringWithFormat:@"執(zhí)行完畢:%@",[NSThread currentThread]];
NSLog(@"%@",str);
});
主隊(duì)列異步任務(wù)
問題:iOS 有a苟呐、b痒芝、c、d 4個異步請求牵素,如果需要a吼野、b、c两波、d順序執(zhí)行,該如何實(shí)現(xiàn)闷哆?
答案:[用主隊(duì)列異步任務(wù)]
//創(chuàng)建一個隊(duì)列腰奋,啟動主線程就可以獲取到主隊(duì)列。
dispatch_queue_t q = dispatch_get_main_queue();
//添加異步任務(wù)
dispatch_async(q, ^{
NSLog(@"添加異步任務(wù)抱怔,并延遲5秒");
[NSThread sleepForTimeInterval:5];
NSString *log1 = [NSString stringWithFormat:@"異步任務(wù)0%@", [NSThread currentThread]];
NSLog(@"%@",str);
});
dispatch_async(q, ^{
[self.logView insert:@"添加異步任務(wù)劣坊,并延遲1秒"];
[NSThread sleepForTimeInterval:1];
NSString *log1 = [NSString stringWithFormat:@"異步任務(wù)1%@", [NSThread currentThread]];
NSLog(@"%@",str);
});
dispatch_async(q, ^{
[self.logView insert:@"添加異步任務(wù)自脯,并延遲10秒"];
[NSThread sleepForTimeInterval:10];
NSString *log1 = [NSString stringWithFormat:@"異步任務(wù)2%@", [NSThread currentThread]];
NSLog(@"%@",str);
});
主隊(duì)列同步任務(wù)(死鎖)
NSLog(@"能執(zhí)行到我");
dispatch_queue_t q = dispatch_get_main_queue();
//同步任務(wù) 死鎖
dispatch_sync(q, ^{
NSLog(@"不能執(zhí)行到我");
});
NSLog(@"不能執(zhí)行到我");
//同步任務(wù)死鎖丈氓,運(yùn)行會報錯。
主隊(duì)列同步任務(wù)(不死鎖)
void (^task)(void) = ^ {
NSLog(@"能執(zhí)行到我 %@", [NSThread currentThread]);
dispatch_queue_t q = dispatch_get_main_queue();
//.同步任務(wù)(不死鎖)
dispatch_sync(q, ^{
NSLog(@"能執(zhí)行到我 %@", [NSThread currentThread]);
});
NSLog(@"能執(zhí)行到我");
};
dispatch_async(dispatch_get_global_queue(0, 0), task);
//同步任務(wù)不死鎖训貌,同步任務(wù)在主線程中執(zhí)行灌危,其它任務(wù)都在子線程中執(zhí)行康二。