GCD:Grand Central Dispatch 官方翻譯:多線程優(yōu)化技術(shù) ,俗稱(chēng)牛逼的中樞調(diào)度器。是Apple開(kāi)發(fā)的一個(gè)多核編程的解決方法,GCD是蘋(píng)果公司為多核的并行運(yùn)算提出的解決方案。
GCD的優(yōu)勢(shì):
1.GCD會(huì)自動(dòng)利用更多的CPU內(nèi)核(比如雙核、四核)
2.GCD會(huì)自動(dòng)管理線程的生命周期(創(chuàng)建線程、調(diào)度任務(wù)、銷(xiāo)毀線程)
3.程序員只需要告訴GCD想要執(zhí)行什么任務(wù),不需要編寫(xiě)任何線程管理代碼(使用方便)
1.基礎(chǔ)并重要的兩個(gè)函數(shù)及隊(duì)列
// 創(chuàng)建隊(duì)列與獲得全局的并發(fā)隊(duì)列
2.創(chuàng)建隊(duì)列的函數(shù)的使用
//創(chuàng)建串行隊(duì)列
// 第一個(gè)參數(shù):隊(duì)列的名稱(chēng),標(biāo)識(shí)
// 第二個(gè)參數(shù):隊(duì)列的類(lèi)型( 創(chuàng)建串行隊(duì)列,隊(duì)列類(lèi)型傳遞NULL或者DISPATCH_QUEUE_SERIAL))
dispatch_queue_t queue1 = dispatch_queue_create("串行隊(duì)列", DISPATCH_QUEUE_SERIAL);
//主隊(duì)列是GCD自帶的一種特殊的串行隊(duì)列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
//創(chuàng)建并發(fā)隊(duì)列
// 第一個(gè)參數(shù):隊(duì)列的名稱(chēng),標(biāo)識(shí)
// 第二個(gè)參數(shù):隊(duì)列的類(lèi)型
dispatch_queue_t queue2 = dispatch_queue_create("并發(fā)隊(duì)列", DISPATCH_QUEUE_CONCURRENT);
//獲取GCD自帶的一種并發(fā)的全局隊(duì)列
// 第一個(gè)參數(shù):隊(duì)列的優(yōu)先級(jí)(默認(rèn)優(yōu)先級(jí)傳0即可)
// 第二個(gè)參數(shù):傳0即可
dispatch_queue_t globleQueue = dispatch_get_global_queue(0, 0);
// 全局并發(fā)隊(duì)列的優(yōu)先級(jí)
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(rèn)(中)
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后臺(tái)
3.同步異步函數(shù)與隊(duì)列的使用
關(guān)于同步函數(shù)和異步函數(shù)與串行隊(duì)列與并發(fā)隊(duì)列的對(duì)執(zhí)行任務(wù)的影響
同步和異步主要影響:能不能開(kāi)啟新的線程
同步:只是在當(dāng)前線程中執(zhí)行任務(wù),不具備開(kāi)啟新線程的能力
異步:可以在新的線程中執(zhí)行任務(wù),具備開(kāi)啟新線程的能力
并發(fā)和串行主要影響:任務(wù)的執(zhí)行方式
并發(fā):允許多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行
串行:一個(gè)任務(wù)執(zhí)行完畢后,再執(zhí)行下一個(gè)任務(wù)
//同步函數(shù)+并發(fā)隊(duì)列:不會(huì)開(kāi)線程,任務(wù)是串行執(zhí)行的
-(void)syncConcurrent
{
//1.創(chuàng)建隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("downloadTask", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"---start---");
//2.封裝任務(wù)
dispatch_sync(queue, ^{
NSLog(@"download1----%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download2----%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download3----%@",[NSThread currentThread]);
});
NSLog(@"---end---");
}
//同步函數(shù)+串行隊(duì)列:不會(huì)開(kāi)線程,任務(wù)是串行執(zhí)行的
-(void)syncSerial
{
//1.創(chuàng)建隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("downloadTask", DISPATCH_QUEUE_SERIAL);
//2.封裝任務(wù)
dispatch_sync(queue, ^{
NSLog(@"download1----%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download2----%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download3----%@",[NSThread currentThread]);
});
}
//異步函數(shù)+主隊(duì)列:所有任務(wù)都在主線程中執(zhí)行,不會(huì)開(kāi)線程
-(void)asyncMain
{
//1.獲得主隊(duì)列
dispatch_queue_t queue = dispatch_get_main_queue();
//2.異步函數(shù)
dispatch_async(queue, ^{
NSLog(@"download1----%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"download2----%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"download3----%@",[NSThread currentThread]);
});
}
//同步函數(shù)+主隊(duì)列:死鎖
//注意:如果該方法在子線程中執(zhí)行,那么所有的任務(wù)在主線程中執(zhí)行,
-(void)syncMain
{
//1.獲得主隊(duì)列
dispatch_queue_t queue = dispatch_get_main_queue();
NSLog(@"start----");
//2.同步函數(shù)
//同步函數(shù):立刻馬上執(zhí)行,如果我沒(méi)有執(zhí)行完畢,那么后面的也別想執(zhí)行
//異步函數(shù):如果我沒(méi)有執(zhí)行完畢,那么后面的也可以執(zhí)行
dispatch_sync(queue, ^{
NSLog(@"download1----%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download2----%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"download3----%@",[NSThread currentThread]);
});
NSLog(@"end---");
}
4.線程中的通信
//從子線程回到主線程
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 執(zhí)行耗時(shí)的異步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程,執(zhí)行UI刷新操作
});
});