zoukankan      html  css  js  c++  java
  • 多线程基本使用方法

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

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

    -----------------------如有转发请注明出处 ,谢谢!
  • 相关阅读:
    [bzoj1072][SCOI2007][排列perm] (状态压缩+数位dp+排列去重)
    [bzoj2461][BeiJing2011][符环] (括号配对+记忆化搜索+高维dp)
    [bzoj4027][HEOI2015][兔子与樱花] (树形dp思想+玄学贪心)
    [bzoj1925][Sdoi2010][地精部落] (序列动态规划)
    [bzoj1004][HNOI2008][Cards] (置换群+Burnside引理+动态规划)
    [bzoj1003][ZJOI2006][物流运输] (最短路+dp)
    [spoj104][Highways] (生成树计数+矩阵树定理+高斯消元)
    [bzoj1002][FJOI2007 轮状病毒] (生成树计数+递推+高精度)
    [bzoj 1001][Beijing2006]狼抓兔子 (最小割+对偶图+最短路)
    [模拟赛FJOI Easy Round #2][T3 skill] (最小割+最大权闭合子图(文理分科模型))
  • 原文地址:https://www.cnblogs.com/purple-sweet-pottoes/p/4630517.html
Copyright © 2011-2022 走看看