GCD?
一塞祈、基本概念
全稱是Grand Central Dispath金刁,純C語言,提供非常多強(qiáng)大的函數(shù)议薪,是目前蘋果官網(wǎng)推薦的多線程開發(fā)方式尤蛮,NSOperation便是基于GCD的封裝
二、GCD的優(yōu)勢(shì)所在
1斯议、為多核的并行運(yùn)算提出了解決方案
2产捞、GCD會(huì)自動(dòng)利用更多的CPU內(nèi)核,比如雙核哼御、四核
3坯临、GCD會(huì)自動(dòng)管理線程的生命周期(創(chuàng)建線程、調(diào)度任務(wù)恋昼、銷毀線程)
4看靠、程序員只需要告訴GCD想要執(zhí)行什么任務(wù),不需要編寫任何線程管理代碼
三液肌、GCD中有2個(gè)核心概念
1挟炬、隊(duì)列:用來存放任務(wù)
1)串行隊(duì)列
只有一個(gè)線程,加入到隊(duì)列中的操作按添加順序依次執(zhí)行嗦哆,一個(gè)任務(wù)執(zhí)行完畢后谤祖,才能再執(zhí)行下一個(gè)任務(wù)
2)并發(fā)隊(duì)列
有多個(gè)線程,操作進(jìn)來以后會(huì)將這些線程安排在可用的處理器上吝秕,同時(shí)保證先進(jìn)來的任務(wù)優(yōu)先處理
PS:GCD中還有一個(gè)特殊隊(duì)列就是主隊(duì)列泊脐,用來執(zhí)行主線程的操作任務(wù)
2、任務(wù):放在隊(duì)列中執(zhí)行
1)同步執(zhí)行
只能在當(dāng)前線程中執(zhí)行任務(wù)烁峭,不具備開啟新線程的能力
2)異步執(zhí)行
可以在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力。
四约郁、GCD做多線程開發(fā)可以抽象成兩步
1缩挑、找到隊(duì)列
1)找到更新UI的主線程所在的隊(duì)列
dispatch_queue_t mainQueue= dispatch_get_main_queue();
2) 創(chuàng)建隊(duì)列
dispatch_queue_t serialQueue = dispatch_queue_create("mySerialQueue", DISPATCH_QUEUE_SERIAL);
第一個(gè)參數(shù):隊(duì)列名字
第二個(gè)參數(shù):隊(duì)列類類型
并行隊(duì)列:DISPATCH_QUEUE_CONCURRENT
串行隊(duì)列:DISPATCH_QUEUE_SERIAL
3)系統(tǒng)內(nèi)部給我們提供有一個(gè)現(xiàn)成的并發(fā)全局隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(0 , 0);
第一個(gè)參數(shù):線程的優(yōu)先級(jí), DISPATCH_QUEUE_PRIORITY_BACKGROUND是最低的。
第二個(gè)參數(shù):系統(tǒng)保留的參數(shù)鬓梅,永遠(yuǎn)傳0
2供置、在隊(duì)列中確定想做的事
1) 使用同步的方式
dispatch_sync(queue, ^{
});
2)使用異步的方式
dispatch_async(queue, ^{
});
五、GCD創(chuàng)建的線程任務(wù)有四種執(zhí)行方式
1绽快、串行隊(duì)列同步執(zhí)行任務(wù)
dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(serialQueue, ^{
NSLog(@"-%@",[NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
NSLog(@"1 - %@", [NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
NSLog(@"2 - %@", [NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
NSLog(@"3 - %@", [NSThread currentThread]);
});
同步不具有開辟新線程的能力芥丧,不會(huì)開辟新的線程去執(zhí)行任務(wù),會(huì)在當(dāng)前線程中順序執(zhí)行任務(wù)坊罢。
2续担、串行隊(duì)列異步執(zhí)行任務(wù)
dispatch_queue_t serialQueue1 = dispatch_queue_create("serialQueue1", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue1, ^{
NSLog(@"1 = %@",[NSThread currentThread]);
});
dispatch_async(serialQueue1, ^{
NSLog(@"2 = %@",[NSThread currentThread]);
});
dispatch_async(serialQueue1, ^{
NSLog(@"3 = %@",[NSThread currentThread]);
});
異步具有創(chuàng)建新線程的能力,會(huì)開辟新的線程去執(zhí)行任務(wù)活孩,但由于是串行物遇,里面只能創(chuàng)建一個(gè)線程,所以還是會(huì)按順序執(zhí)行
3憾儒、并行隊(duì)列同步執(zhí)行任務(wù)
dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(concurrentQueue, ^{
NSLog(@"1 = %@",[NSThread currentThread]);
});
dispatch_sync(concurrentQueue, ^{
NSLog(@"2 = %@",[NSThread currentThread]);
});
dispatch_sync(concurrentQueue, ^{
NSLog(@"3 = %@",[NSThread currentThread]);
});
同步不具有創(chuàng)建新線程的能力询兴,不會(huì)開辟新的線程去執(zhí)行任務(wù),會(huì)在當(dāng)前線程去執(zhí)行任務(wù)
4起趾、并發(fā)隊(duì)列異步執(zhí)行任務(wù)(常用)
dispatch_queue_t concurrentQueue1 = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue1, ^{
NSLog(@"1 = %@",[NSThread currentThread]);
});
dispatch_async(concurrentQueue1, ^{
NSLog(@"2 = %@",[NSThread currentThread]);
});
dispatch_async(concurrentQueue1, ^{
NSLog(@"3 = %@",[NSThread currentThread]);
});
并行隊(duì)列可以里可以有多個(gè)線程诗舰,同步執(zhí)行的方式又可以開辟多個(gè)線程,所以這里實(shí)現(xiàn)了多個(gè)線程并行執(zhí)行,沒有按照順序
六训裆、GCD組的應(yīng)用
GCD中可以將一組相關(guān)聯(lián)的操作始衅,定義到一個(gè)群組中
定義到群組中之后,當(dāng)所有線程完成時(shí)缭保,可以獲得通知
0汛闸、創(chuàng)建全局隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
1、定義群組
dispatch_group_t group = dispatch_group_create();
2艺骂、定義群組的異步任務(wù)
dispatch_group_async(group, queue, ^{
});
dispatch_group_async(group, queue, ^{
});
3诸老、群組任務(wù)完成通知
dispatch_group_notify(group, queue, ^{
});
1)dispatch_group_notify可以監(jiān)聽一組任務(wù)是否完成。這個(gè)方法很有用钳恕,比如你執(zhí)行三個(gè)下載任務(wù)别伏,當(dāng)三個(gè)任務(wù)都下載完成后,才通知界面說已經(jīng)完成
2)如果不需要監(jiān)聽一組任務(wù)忧额,可以直接使用dispatch_async方法
六厘肮、線程鎖
1、在多線程應(yīng)用中睦番,所有被搶奪資源的屬性需要設(shè)置為原子屬性,atomic屬性类茂,必須與@synchronized(同步鎖)一起使用
2耍属、系統(tǒng)會(huì)在多線程搶奪時(shí),保證該屬性有且僅有一個(gè)線程能夠訪問
3巩检、操作步驟
1)將資源屬性設(shè)置原子屬性
2)將處理該屬性的代碼放到線程鎖中
@synchronized (self) {
}