今天抽空對多線程GCD復(fù)習(xí)了一下,并進(jìn)行了總結(jié):
一、術(shù)語:同步、異步、并發(fā)、串行
1、同步和異步?jīng)Q定了要不要開啟新的線程
同步:在當(dāng)前線程執(zhí)行,不開啟新線程
dispatch_sync,同步操作,派發(fā)到任何隊(duì)列,都不會開啟新線程。
異步:在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力
dispatch_async,異步操作,會創(chuàng)建一個(gè)線程。如果派發(fā)到主線程中,則會在主線程中執(zhí)行。
2、并發(fā)和串行決定了任務(wù)的執(zhí)行方式
并發(fā)隊(duì)列 :多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行
串行隊(duì)列 :一個(gè)任務(wù)執(zhí)行完畢后,再執(zhí)行下一個(gè)任務(wù)
特殊隊(duì)列主隊(duì)列 : 用來執(zhí)行主線程上的操作任務(wù)
二、特點(diǎn):GCD中有三種隊(duì)列類型
1、主隊(duì)列:dispatch_get_main_queue();與主線程功能相同;串行隊(duì)列,做線程間通訊的(后臺線程完成工作后,通知主線程更新UI);
2、全局隊(duì)列(并發(fā)隊(duì)列):dispatch_get_global_queue
函數(shù),第一個(gè)參數(shù)傳入優(yōu)先級,第二個(gè)參數(shù)傳0;并發(fā)隊(duì)列,能夠開多條線程;
3、用戶隊(duì)列(串行隊(duì)列,手動創(chuàng)建):dispatch_queue_create
創(chuàng)建;第一個(gè)參數(shù)是一個(gè)標(biāo)簽,這純是為了debug,第二個(gè)參數(shù)目前還不支持,傳入NULL就行;串行隊(duì)列,最多能開一條線程;
三、 常用的GCD代碼示例:
1、全局隊(duì)列的異步任務(wù)+主線程更新界面:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//需要在后臺執(zhí)行的代碼塊;
...
...
//執(zhí)行完畢在主線程更新UI
dispatch_async(dispatch_get_main_queue(), ^{
//更新UI操作
...
});
});
2、全局隊(duì)列+dispath_group_async()的方式
/*
使用GCD進(jìn)行多文件下載時(shí),可以使用dispatch_group進(jìn)行管理。可以等到他們都響應(yīng)完,在執(zhí)行下一步操作,
把耗時(shí)的下載圖片的的任務(wù)加到全局隊(duì)列中,以group為單位可以很方便的管理下載后再執(zhí)行什么操作
*/
//隊(duì)列:全局隊(duì)列
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
//創(chuàng)建group
dispatch_group_t group = dispatch_group_create();
//執(zhí)行方式:dispath_group_async()
dispatch_group_async(group, globalQueue, ^{
//并行執(zhí)行的線程一
NSLog(@"下載圖片1的線程--->%@",[NSThread currentThread]);
[self downLoad1];
});
dispatch_group_async(group, globalQueue, ^{
//并行執(zhí)行的線程二
NSLog(@"下載圖片2的線程--->%@",[NSThread currentThread]);
[self downLoad2];
});
dispatch_group_async(group, globalQueue, ^{
//并行執(zhí)行的線程三
NSLog(@"下載圖片3的線程--->%@",[NSThread currentThread]);
[self downLoad3];
});
dispatch_group_async(group, globalQueue, ^{
//并行執(zhí)行的線程四
NSLog(@"下載圖片4的線程--->%@",[NSThread currentThread]);
[self downLoad4];
});
//通知以上圖片下載完畢
dispatch_group_notify(group, globalQueue, ^{
NSLog(@"全部下載完畢!,線程---->%@",[NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"回到主線程更新UI---->%@",[NSThread currentThread]);
});
});
3、單例:dispatch_once_t在多線程執(zhí)行時(shí)能夠保證只執(zhí)行一次block塊代碼。
// static保存在靜態(tài)區(qū),程序啟動就存在,隨著程序一起銷毀
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"該行代碼只執(zhí)行一次");
});
4、延時(shí)處理:調(diào)用dispatch_after函數(shù)
/*
dispatch_time_t:
第一個(gè)參數(shù),指定的時(shí)間開始,經(jīng)常使用DISPATCH_TIME_NOW,表示現(xiàn)在的時(shí)間。
第二個(gè)參數(shù)指定的毫微秒單位時(shí)間:
NSEC_PER_MSEC毫秒
NSEC_PER_SEC秒
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(100 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//Do something
});
Demo地址:https://github.com/zhuchenglong/GCD-

6910338E-62B9-4EC5-A379-2893E38B19ED.png