多线程 —— GCD
来源:互联网 发布:seo实战密码 epub 编辑:程序博客网 时间:2024/04/30 09:42
什么是GCD
全称是Grand Central Dispatch,可译为“牛逼的中枢调度器”
纯C语言,提供了非常多强大的函数
GCD的优势
GCD是苹果公司为多核的并行运算提出的解决方案
GCD会自动利用更多的CPU内核(比如双核、四核)
GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码
GCD中有2个核心概念
任务:执行什么操作
队列:用来存放任务
GCD的使用就2个步骤
1、定制任务:确定想做的事情
2、将任务添加到队列中
GCD会自动将队列中的任务取出,放到对应的线程中执行
任务的取出遵循队列的FIFO原则:先进先出,后进后出执行任务
GCD中有2个用来执行任务的函数
用同步的方式执行任务
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
queue:队列
block:任务
用异步的方式执行任务
dispatch_async(dispatch_queue_t queue,dispatch_block_t block);
同步和异步的区别
同步:在当前线程中执行
异步:在另一条线程中执行
队列的类型
GCD的队列可以分为2大类型
并发队列(Concurrent Dispatch Queue)
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
并发功能只有在异步(dispatch_async)函数下才有效
串行队列(Serial Dispatch Queue)
让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
容易混淆的术语
同步和异步决定了要不要开启新的线程
同步:在当前线程中执行任务,不具备开启新线程的能力
异步:在新的线程中执行任务,具备开启新线程的能力
并发和串行决定了任务的执行方式
并发:多个任务并发(同时)执行
串行:一个任务执行完毕后,再执行下一个任务
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
四种组合方式:
1、串行队列,同步执行任务
<span style="font-size:18px;"><span style="font-size:18px;">// 1. 创建一个串行队列 //参数:1. 队列标签 2. 队列的属性 dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL); NSLog(@"开始!!"); // 2. 同步执行任务 // 一般只要使用”同步“执行,串行队列对添加的同步任务,会立马执行 dispatch_sync(queue, ^{ NSLog(@"%@", [NSThread currentThread]); });</span></span>
2、串行队列,异步(开启多个线程)执行任务
<span style="font-size:18px;"><span style="font-size:18px;"> // 1. 串行队列 // 下面两种写法是一样的// dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL); dispatch_queue_t queue = dispatch_queue_create("itcast", NULL); // 2. 异步执行 for (int i = 0; i < 10; i++) { dispatch_async(queue, ^{ NSLog(@"%@ %d", [NSThread currentThread], i); }); }</span></span>
3、并行队列,同步执行任务
<span style="font-size:18px;"><span style="font-size:18px;">//1. 并行队列 dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT); // 2. 同步执行任务 for (int i = 0; i < 10; i++) { dispatch_sync(queue, ^{ NSLog(@"%@ %d", [NSThread currentThread], i); }); }</span></span>
4、并行队列,异步执行任务
<span style="font-size:18px;"><span style="font-size:18px;"> //1. 并行队列 dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT); // 2. 异步执行任务 for (int i = 0; i < 10; i++) { dispatch_async(queue, ^{ NSLog(@"%@ %d", [NSThread currentThread], i); }); }</span></span>
主队列:
<span style="font-size:18px;">/** 主队列:专门负责在主线程上调度任务,不会在子线程调度任务,在主队列不允许开新线程. 异步执行: 会开新线程,在新线程执行 结果: 不开线程, 只能在主线程上面,顺序执行! */- (void)gcdTest5{ // 1. 获得主队列-> 程序启动,--> 至少有一个主线程-> 一开始就会创建主队列 dispatch_queue_t queue = dispatch_get_main_queue(); NSLog(@"1----"); // 2. 异步执行任务 for (int i = 0; i < 10; i++) { NSLog(@"调度前---"); // 异步:把任务放到主队列里,但是不需要马上执行 dispatch_async(queue, ^{ NSLog(@"%@ %d", [NSThread currentThread], i); }); NSLog(@"睡会"); [NSThread sleepForTimeInterval:2.0]; } NSLog(@"完成----");}</span>
/**
主队列:专门负责在主线程上调度任务,不会在子线程调度任务,在主队列不允许开新线程.
同步执行:要马上执行
结果:死锁
*/
<span style="font-size:18px;">#pragma GCD- 同步任务的作用- (void)gcdTest7{ // 并发队列 dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT); /** 例子:有一个小说网站 - 必须登录,才能下载小说 有三个任务: 1. 用户登录 2. 下载小说A 3. 下载小说B */ // 添加任务 // 同步任务,需要马上执行。 不开新线程 dispatch_sync(queue, ^{ NSLog(@"用户登录 %@", [NSThread currentThread]); }); // dispatch_async(queue, ^{ NSLog(@"下载小说A %@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"下载小说B %@", [NSThread currentThread]); });}</span>
全局队列:也是并发队列
/** 全局队列跟并发队列的区别 1. 全局队列没有名称 并发队列有名称 2. 全局队列,是供所有的应用程序共享。 3. 在MRC开发,并发队列,创建完了,需要释放。 全局队列不需要我们管理 */#pragma CGD - 全局队列- (void)gcdTest8{ // 获得全局队列 /** 参数:第一个参数,一般 写 0(可以适配 iOS 7 & 8) iOS 7 DISPATCH_QUEUE_PRIORITY_HIGH 2 高优先级 DISPATCH_QUEUE_PRIORITY_DEFAULT 0 默认优先级 DISPATCH_QUEUE_PRIORITY_LOW (-2) 低优先级 DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后台优先级 iOS 8 QOS_CLASS_DEFAULT 0 第二个参数:保留参数 0 */ dispatch_queue_t queue = dispatch_get_global_queue(0, 0); // 添加异步任务 for (int i = 0; i < 10; i++) { dispatch_async(queue, ^{ NSLog(@"%@ %d", [NSThread currentThread], i); }); } }
队列的选择:
串行队列异步执行
- 开一条线程,顺序执行
- 效率:不高,执行比较慢,资源占用小 -》省电
一般网络是3G,对想能要求不会很高。
并发队列异步执行
- 开启多条线程,并发执行
- 效率:高,执行快,资源消耗大-》费电
使用场合:
- 网络WiFi,或者需要很快的响应,要求用户体验非常流畅。
-对任务执行顺序没有要求
-同步任务:一般只会在并发队列,需要阻塞后续任务。必须等待同步任务执行完毕,再去执行其他任务。"依赖"关系
线程间的通讯:(重点)
<span style="font-size:18px;">- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"%@", [NSThread currentThread]); // 耗时操作: 放在全局队列,异步执行 // 1. url, 确定一个网络上的资源路径 NSURL *url = [NSURL URLWithString:@"http://fe.topit.me/e/d1/12/1170068721aa112d1el.jpg"]; // 2. 通过url可以下载对应的网络资源, 网络资源传输的都是二进制 NSData *data = [NSData dataWithContentsOfURL:url]; // 3. 二进制转成图片 UIImage *image = [UIImage imageWithData:data]; // 4. 更新UI,在主线程-》 直接把任务添加到主队列,就会在主队列执行 dispatch_async(dispatch_get_main_queue(), ^{ self.iconView.image = image; NSLog(@"-----%@", [NSThread currentThread]); }); }); }</span>
其他用法:
<span style="font-size:18px;">#pragma mark - 调度组(分组)- (void)group{ /** 应用场景: 开发的时候,有的时候出现多个网络请求都完成以后(每一个网络请求的事件长短不一定),再统一通知用户 比如: 下载小说:三国演义, 红楼梦, 金X梅 */ // 实例化一个调度组 dispatch_group_t group = dispatch_group_create(); // 队列 dispatch_queue_t queue = dispatch_get_global_queue(0, 0); // 任务添加到队列queue dispatch_group_async(group, queue, ^{ NSLog(@"下载小说A---%@", [NSThread currentThread]); }); dispatch_group_async(group, queue, ^{ NSLog(@"下载小说B---%@", [NSThread currentThread]); }); dispatch_group_async(group, queue, ^{ NSLog(@"下载小说X---%@", [NSThread currentThread]); }); // 获得所有调度组里面的异步任务完成的通知// dispatch_group_notify(group, queue, ^{// NSLog(@"下载完成,请观看%@", [NSThread currentThread]); // 异步的// }); //注意点: 在调度组完成通知里,可以跨队列通信 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 更新UI,在主线程 NSLog(@"下载完成,请观看%@", [NSThread currentThread]); // 异步的 });}</span>
延时执行:
<span style="font-size:18px;"> dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"点我了-- %@", [NSThread currentThread]); });</span>
一次性任务:
<span style="font-size:18px;"> dispatch_once(&onceToken, ^{ NSLog(@"%----ld", onceToken); NSLog(@"真的执行一次么?"); });</span>
0 0
- 多线程 —— GCD
- 多线程——GCD
- 《多线程——GCD》
- 多线程 —— GCD
- iOS多线程——GCD
- iOS多线程——GCD
- 多线程——GCD(并发)
- iOS - 多线程——GCD
- IOS多线程之——GCD。
- IOS多线程之——GCD(二)
- IOS多线程之——GCD总结。
- iOS —— 多线程之GCD
- 多线程——GCD(串行队列)
- iOS多线程编程——浅谈GCD
- GCD 多线程——串行队列
- 多线程——GCD(串行队列)
- iOS多线程——GCD初级介绍
- iOS开发多线程篇—GCD介绍
- Java回调函数的理解
- 安装Ubuntu 15 Kylin 网络线口不亮 连不上网 网络驱动更换[终极解决办法]
- SDUT-二叉树先序 中序建树求树高
- 二胎
- Cocos2d-x 中加载骨骼动画资源
- 多线程 —— GCD
- Java自动装箱和自动拆箱源码分析
- hdu1010 Tempter of the Bone
- 数据结构基础:数组和链表
- hdu 2199
- 聊聊Universal framework原理
- jsp forward与redirect比较
- 软件测试相关的生命周期总结
- 进程(线程)间的同步互斥问题(五) 读者-作者问题