1 - 並發隊列(Concurrent Dispatch Queue) 可以讓多個任務並發(同時)執行(自動開啟多個線程同時執行任務) 並發功能只有在異步(dispatch_async)函數下才有效
2 - 串行隊列(Serial Dispatch Queue) 讓任務一個接著一個地執行(一個任務執行完畢後,再執行下一個任務)
同步:只能在當前線程中執行任務,不具備開啟新線程的能力 異步:可以在新的線程中執行任務,具備開啟新線程的能力
一、創建任務
二、將任務添加到隊列中
GCD會自動將隊列中的任務取出,放到對應的線程中執行
任務的取出遵循隊列的FIFO原則:先進先出,後進後出
1、創建一個串行隊列
/**
* 創建一個串行隊列
*
* @param "Mazy" 隊列的標示符
* @param DISPATCH_QUEUE_SERIAL 串行隊列
DISPATCH_QUEUE_CONCURRENT 並發隊列
*
* @return 返回串行隊列
*/
dispatch_queue_t serialQueue = dispatch_queue_create("Mazy", DISPATCH_QUEUE_SERIAL);
2、創建一個並發隊列
/**
* 創建一個並發隊列
*
* @param "Mazy" 隊列的標示符
* @param DISPATCH_QUEUE_CONCURRENT 並發隊列
*
* @return 返回並發隊列
*/
dispatch_queue_t concurrentQueue = dispatch_queue_create("Mazy", DISPATCH_QUEUE_CONCURRENT);
3、獲得全局並發隊列
/**
* 獲得全局並發隊列
*
* @param DISPATCH_QUEUE_PRIORITY_DEFAULT 線程隊列的優先級
DISPATCH_QUEUE_PRIORITY_HIGH 2 高
DISPATCH_QUEUE_PRIORITY_DEFAULT 0 一般 默認
DISPATCH_QUEUE_PRIORITY_LOW (-2) 低
DISPATCH_QUEUE_PRIORITY_BACKGROUND 很低
* @param 0 系統保留參數
*
* @return 返回全局並發隊列
*/
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
3、獲得主隊列
/**
* 獲得主隊列
*
* @return 返回主線程隊列
*/
dispatch_queue_t mainQueue = dispatch_get_main_queue();
1、同步 + 串行隊列
// 同步 + 串行隊列:不會開啟新的線程,在當前線程執行任務。任務是串行的,執行完一個任務,再執行下一個任務
-(void)sync_serial {
// 創建一個串行隊列
dispatch_queue_t queue = dispatch_queue_create("Mazy", DISPATCH_QUEUE_SERIAL);
// 同步執行三個任務
dispatch_sync(queue, ^{
NSLog(@"1 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3 %@",[NSThread currentThread]);
});
}
打印結果:
總結:沒有創建新線程,主線程執行任務,任務串行執行
2、異步 + 串行隊列
// 異步 + 串行隊列:開啟新的線程,但只開啟一條
-(void)async_serial {
// 創建一個串行隊列
dispatch_queue_t queue = dispatch_queue_create("Mazy", DISPATCH_QUEUE_SERIAL);
// 異步執行三個任務
dispatch_async(queue, ^{
NSLog(@"1 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3 %@",[NSThread currentThread]);
});
}
打印結果:
總結:開啟了一條線程,任務串行執行
3、同步 + 並發隊列
// 同步 + 並發隊列:不會開啟新的線程
-(void)sync_concurrent {
// 創建一個全局並發隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 同步執行三個任務
dispatch_sync(queue, ^{
NSLog(@"1 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3 %@",[NSThread currentThread]);
});
}
打印結果:
總結:不開啟新線程,主線程執行任務,任務也是順序執行
4、異步 + 並發隊列
// 異步 + 並發隊列:同時開啟多條線程
-(void)async_concurrent {
// 創建一個全局並發隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 異步執行三個任務
dispatch_async(queue, ^{
NSLog(@"1 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3 %@",[NSThread currentThread]);
});
}
打印結果:
總結:開啟多條線程,並發執行任務
從子線程回到主線程
從子線程回到主線程
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 執行耗時的異步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程,執行UI刷新操作
});
});
線程之間的通信具體實現實例
// 創建 異步 全局並發隊列
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 圖片的網絡路徑
NSURL *url = [NSURL URLWithString:@"http://xxx.jpg"];
// 加載圖片
NSData *data = [NSData dataWithContentsOfURL:url];
// 生成圖片
UIImage *image = [UIImage imageWithData:data];
// 回到主線程設置圖片
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = image;
});
});
延遲執行
/**
* 延遲執行
*/
-(void)delay {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"---我被延遲了3秒執行---");
});
}
其他延遲執行方法
// method 1
[self performSelector:@selector(do_method) withObject:nil afterDelay:3.0];
// method 2
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(do_method) userInfo:nil repeats:NO];
只執行一次(用於實現單例模式)
/**
* 只執行一次
*/
-(void)onlyOnce {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"---我只會被執行一次---");
});
}
快速遍歷
/**
* 快速遍歷
*/
-(void)apply {
// 創建一個全局並發隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSInteger count = 10;
dispatch_apply(count, queue, ^(size_t index) {
NSLog(@"%zd--%@",index,[NSThread currentThread]);
});
}
打印結果:
總結:開啟多條線程執行任務,速度遠比(for…in…) 遍歷快,對於無序的遍歷,此方法比較合適
創建線程群組
例如同一個文件分段下載,待所有分段任務下載完成後,合並任務
/**
* 創建線程群組
*/
-(void)group {
// 創建一個全局並發隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 創建一個隊列組
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"我是任務-1 %@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"我是任務-2 %@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"我是任務-3 %@",[NSThread currentThread]);
});
// 待群組中的每個任務執行完成後,執行此方法
dispatch_group_notify(group, queue, ^{
NSLog(@"我是終極任務,只有在group裡面的任務執行完畢後才執行");
NSLog(@"%@",[NSThread currentThread]);
});
}
打印結果:
總結:開啟多條線程,去執行群組中的任務,當群組內的三個任務執行完畢後,再去執行notify裡面的任務
創建屏障線程隊列
/**
* 創建屏障線程隊列
*/
-(void)barrier {
// 創建一個並發隊列
dispatch_queue_t queue = dispatch_queue_create("Mazy", DISPATCH_QUEUE_CONCURRENT);
// 創建四個異步任務
dispatch_async(queue, ^{
NSLog(@"我是任務-1 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"我是任務-2 %@",[NSThread currentThread]);
});
// 創建屏障線程隊列
dispatch_barrier_async(queue, ^{
NSLog(@"----barrier-----%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"我是任務-3 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"我是任務-4 %@",[NSThread currentThread]);
});
}
打印結果:
總結:會優先執行屏障前面的任務,當屏障前的所有任務執行完畢後,再去執行後面的任務