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]);
});
}
打印结果:
总结:会优先执行屏障前面的任务,当屏障前的所有任务执行完毕后,再去执行后面的任务