多线程基本使用方法

  关于多线程的使用属于重点掌握知识,今天总结一下自己已经学到的多线程使用方法。多线程使用方法现阶段主要使用了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中就能做好多线程开发。 

如文中有何错误,希望大家指出!

-----------------------如有转发请注明出处 ,谢谢!
原文地址:https://www.cnblogs.com/purple-sweet-pottoes/p/4630517.html