多线程基本使用方法
2015-07-08 16:08
302 查看
关于多线程的使用属于重点掌握知识,今天总结一下自己已经学到的多线程使用方法。多线程使用方法现阶段主要使用了3种。1:GCD(个人觉得这个属于最常用方法,因为其贴近底层,执行效率更高) 2.
NSOperation(使用率较高,属于苹果封装好的GCD类,面向对象更好理解) 3.NSThread(个人使用较少,创建好对象后需要自己手动启动线程)
从结果分析我们达到了多条线程异步下载的效果
异步串行队列
从此结果分析,异步串行队列实质上只开辟一个子线程,并且按顺序执行之前自己添加的操作
异步组队列
组队列操作的好处是让我们先执行某些操作 在操作执行完成后再执行什么操作。
NSBlockOperation 使用
增加的额外线程只会在其第一个操作执行完成后再异步执行。这样当多个操作都依赖于一个操作完成时执行,此方法比较适用
说完NSBlockOperation,必须提一下NSOperationQueue的使用,因为一般NSBlockOperation对象都是加入NSOperationQueue对象中使用,这样不用自己手动启动线程
队列中所有操作都异步执行,其中
相当于
这种写法方便了程序员编写代码,达到代码简化的效果,此处主队列串行的结果图就不上传了
异步队列依赖关系设置(达到上述GCD中组队列效果)
此处运行了2次demo,可以发现 B、C都是在A完成后才进行的操作。达到了依赖效果。
关于NSThread此处就不提了,因为其使用率较低,掌握好上述2中就能做好多线程开发。
如文中有何错误,希望大家指出!
NSOperation(使用率较高,属于苹果封装好的GCD类,面向对象更好理解) 3.NSThread(个人使用较少,创建好对象后需要自己手动启动线程)
1.GCD
多条异步线程启用,此方法中首先创建一个异步队列,因为所有的线程都需要加入队列才能得到使用,然后创建4个子线程操作加入队列,这样异步线程开启,GCD会自动管理线程,我们只需要关心我们要做什么操作即可1 - (void)demo1{ 2 /** 优先级 3 * #define DISPATCH_QUEUE_PRIORITY_HIGH 2 优先 4 * #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 正常 5 * #define DISPATCH_QUEUE_PRIORITY_LOW (-2) 低 6 * #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后台 7 */ 8 //创建异步队列 9 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 10 //往队列里添加线程操作 11 dispatch_async(queue, ^{ 12 NSLog(@"---下载图片1--%@",[NSThread currentThread]); 13 }); 14 dispatch_async(queue, ^{ 15 NSLog(@"---下载图片2--%@",[NSThread currentThread]); 16 }); 17 dispatch_async(queue, ^{ 18 NSLog(@"---下载图片3--%@",[NSThread currentThread]); 19 }); 20 dispatch_async(queue, ^{ 21 NSLog(@"---下载图片4--%@",[NSThread currentThread]); 22 }); 23 }
从结果分析我们达到了多条线程异步下载的效果
异步串行队列
- (void)demo2{ /** * 串行队列创建 * @param "Myqueue.test" 标识符 * @param NULL 一般为NULL */ dispatch_queue_t queue = dispatch_queue_create("Myqueue.test", NULL); //开启异步线程 dispatch_async(queue, ^{ NSLog(@"---下载图片1--%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"---下载图片2--%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"---下载图片3--%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"---下载图片4--%@",[NSThread currentThread]); }); }
从此结果分析,异步串行队列实质上只开辟一个子线程,并且按顺序执行之前自己添加的操作
异步组队列
- (void)demo3{ //设置异步队列 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_async(group, queue, ^{ NSLog(@"---下载图片4--%@",[NSThread currentThread]); }); //组队列操作执行完成后调用 dispatch_group_notify(group, queue, ^{ NSLog(@"下载完成"); }); }
组队列操作的好处是让我们先执行某些操作 在操作执行完成后再执行什么操作。
2.NSOperation
NSOperation的使用一般都是基于其子类NSBlockOperation,使用方法如下NSBlockOperation 使用
- (void)demo4{ //NSBlockOperation start使用方法 dispatch_async(dispatch_queue_create("123", NULL), ^{ NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"---下载图片1--%@",[NSThread currentThread]); }]; //增加额外线程 addExecutionBlock 额外线程是在operation1主线程执行后 再异步执行 [operation1 addExecutionBlock:^{ NSLog(@"---下载图片2--%@",[NSThread currentThread]); }]; [operation1 addExecutionBlock:^{ NSLog(@"---下载图片3--%@",[NSThread currentThread]); }]; [operation1 addExecutionBlock:^{ NSLog(@"---下载图片4--%@",[NSThread currentThread]); }]; //用start 直接使用当前线程 [operation1 start]; }); }
增加的额外线程只会在其第一个操作执行完成后再异步执行。这样当多个操作都依赖于一个操作完成时执行,此方法比较适用
说完NSBlockOperation,必须提一下NSOperationQueue的使用,因为一般NSBlockOperation对象都是加入NSOperationQueue对象中使用,这样不用自己手动启动线程
1 - (void)demo5{ 2 //创建异步队列 3 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 4 //创建主线程队列 5 // NSOperationQueue *queue = [NSOperationQueue mainQueue]; 6 //若为主线程 则相当于串行队列 7 [queue addOperationWithBlock:^{ 8 NSLog(@"---下载图片1--%@",[NSThread currentThread]); 9 }]; 10 [queue addOperationWithBlock:^{ 11 NSLog(@"---下载图片2--%@",[NSThread currentThread]); 12 }]; 13 //创建操作 14 NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ 15 NSLog(@"---下载图片1--%@",[NSThread currentThread]); 16 }]; 17 NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ 18 NSLog(@"---下载图片2--%@",[NSThread currentThread]); 19 }]; 20 NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{ 21 NSLog(@"---下载图片3--%@",[NSThread currentThread]); 22 }]; 23 NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{ 24 NSLog(@"---下载图片4--%@",[NSThread currentThread]); 25 }]; 26 //将操作添加进队列 27 [queue addOperation:operation1]; 28 [queue addOperation:operation2]; 29 [queue addOperation:operation3]; 30 [queue addOperation:operation4]; 31 }
队列中所有操作都异步执行,其中
[queue addOperationWithBlock:^{ NSLog(@"---A--%@",[NSThread currentThread]); }];
相当于
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"---A--%@",[NSThread currentThread]); }]; [queue addOperation:operation];
这种写法方便了程序员编写代码,达到代码简化的效果,此处主队列串行的结果图就不上传了
异步队列依赖关系设置(达到上述GCD中组队列效果)
- (void)demo7{ //创建异步队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; //创建操作 NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"-----A------"); }]; NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"-----B------"); }]; NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"-----C------"); }]; //设置依赖关系 不能相互依赖 [operationB addDependency:operationA]; [operationC addDependency:operationA]; //将操作写进队列 [queue addOperation:operationA]; [queue addOperation:operationB]; [queue addOperation:operationC]; }
此处运行了2次demo,可以发现 B、C都是在A完成后才进行的操作。达到了依赖效果。
关于NSThread此处就不提了,因为其使用率较低,掌握好上述2中就能做好多线程开发。
如文中有何错误,希望大家指出!
相关文章推荐
- openssl nodejs https+客户端证书+usbkey
- Chapter 30 Web Technology and DBMSs
- servlet开发中的一些细节
- 第七章 function
- windows下phpstorm的快捷键
- mysql --mysqli::multi_query 和 mysqli_multi_query
- Dokcer学习笔记之容器管理命令
- 开启mysql慢查询,重启提示Starting MySQL.The server quit without updating PID file
- Hibernate延迟加载实现原理
- 深入浅出数据仓库中SQL性能优化之Hive篇
- WCF - Consuming WCF Service
- vim颜色选择+按<F9>自动编译运行+其他基本配置(ubuntu)
- android打开网页
- 触发器insert后update当前行字段
- linux中安装easy_install(setuptools)
- Spring PropertyPlaceholderConfigure 加载配置文件
- Java Classloader机制解析
- 关于如何在sql数据库里查询多次返回数据的做法
- Spring框架包含的模块
- Implement Stack using Queues