多线程基本使用方法
关于多线程的使用属于重点掌握知识,今天总结一下自己已经学到的多线程使用方法。多线程使用方法现阶段主要使用了3种。1:GCD(个人觉得这个属于最常用方法,因为其贴近底层,执行效率更高) 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 }
从结果分析我们达到了多条线程异步下载的效果
异步串行队列
1 - (void)demo2{ 2 /** 3 * 串行队列创建 4 * @param "Myqueue.test" 标识符 5 * @param NULL 一般为NULL 6 */ 7 dispatch_queue_t queue = dispatch_queue_create("Myqueue.test", NULL); 8 //开启异步线程 9 dispatch_async(queue, ^{ 10 NSLog(@"---下载图片1--%@",[NSThread currentThread]); 11 }); 12 dispatch_async(queue, ^{ 13 NSLog(@"---下载图片2--%@",[NSThread currentThread]); 14 }); 15 dispatch_async(queue, ^{ 16 NSLog(@"---下载图片3--%@",[NSThread currentThread]); 17 }); 18 dispatch_async(queue, ^{ 19 NSLog(@"---下载图片4--%@",[NSThread currentThread]); 20 }); 21 }
从此结果分析,异步串行队列实质上只开辟一个子线程,并且按顺序执行之前自己添加的操作
异步组队列
1 - (void)demo3{ 2 //设置异步队列 3 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 4 //设置组队列 5 dispatch_group_t group = dispatch_group_create(); 6 dispatch_group_async(group, queue, ^{ 7 NSLog(@"---下载图片1--%@",[NSThread currentThread]); 8 }); 9 dispatch_group_async(group, queue, ^{ 10 NSLog(@"---下载图片2--%@",[NSThread currentThread]); 11 }); 12 dispatch_group_async(group, queue, ^{ 13 NSLog(@"---下载图片3--%@",[NSThread currentThread]); 14 }); 15 dispatch_group_async(group, queue, ^{ 16 NSLog(@"---下载图片4--%@",[NSThread currentThread]); 17 }); 18 //组队列操作执行完成后调用 19 dispatch_group_notify(group, queue, ^{ 20 NSLog(@"下载完成"); 21 }); 22 }
组队列操作的好处是让我们先执行某些操作 在操作执行完成后再执行什么操作。
2.NSOperation
NSOperation的使用一般都是基于其子类NSBlockOperation,使用方法如下
NSBlockOperation 使用
1 - (void)demo4{ 2 //NSBlockOperation start使用方法 3 dispatch_async(dispatch_queue_create("123", NULL), ^{ 4 NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ 5 NSLog(@"---下载图片1--%@",[NSThread currentThread]); 6 }]; 7 //增加额外线程 addExecutionBlock 额外线程是在operation1主线程执行后 再异步执行 8 [operation1 addExecutionBlock:^{ 9 NSLog(@"---下载图片2--%@",[NSThread currentThread]); 10 }]; 11 [operation1 addExecutionBlock:^{ 12 NSLog(@"---下载图片3--%@",[NSThread currentThread]); 13 }]; 14 [operation1 addExecutionBlock:^{ 15 NSLog(@"---下载图片4--%@",[NSThread currentThread]); 16 }]; 17 //用start 直接使用当前线程 18 [operation1 start]; 19 }); 20 }
增加的额外线程只会在其第一个操作执行完成后再异步执行。这样当多个操作都依赖于一个操作完成时执行,此方法比较适用
说完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中组队列效果)
1 - (void)demo7{ 2 //创建异步队列 3 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 4 //创建操作 5 NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{ 6 NSLog(@"-----A------"); 7 }]; 8 NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{ 9 NSLog(@"-----B------"); 10 }]; 11 NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{ 12 NSLog(@"-----C------"); 13 }]; 14 //设置依赖关系 不能相互依赖 15 [operationB addDependency:operationA]; 16 [operationC addDependency:operationA]; 17 //将操作写进队列 18 [queue addOperation:operationA]; 19 [queue addOperation:operationB]; 20 [queue addOperation:operationC]; 21 }
此处运行了2次demo,可以发现 B、C都是在A完成后才进行的操作。达到了依赖效果。
关于NSThread此处就不提了,因为其使用率较低,掌握好上述2中就能做好多线程开发。
如文中有何错误,希望大家指出!