zoukankan      html  css  js  c++  java
  • IOS学习笔记 -- 多线程

    多线程
    1.多线程的原理
      1>.同一时间,CPU只能处理1条线程,只有1条线程在工作(执行)
      2>.多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换)
      3>.如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象
    如果线程非常非常多,会发生:
      1>.CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源
      2>.每条线程被调度执行的频次会降低(线程的执行效率降低)

    2.多线程的优缺点
      1>.多线程的优点
        能适当提高程序的执行效率
        能适当提高资源利用率(CPU、内存利用率)
      2>.多线程的缺点
        开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能
        线程越多,CPU在调度线程上的开销就越大
        程序设计更加复杂:比如线程之间的通信、多线程的数据共享

    3.主线程
      一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”
       1>.主线程的主要作用
      显示刷新UI界面
      处理UI事件(比如点击事件、滚动事件、拖拽事件等)
      2>.主线程的使用注意
      别将比较耗时的操作放到主线程中
      耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种“卡”的坏体验

    4.NSThread
      1> 开线程的几种方式
        * 先创建,后启动
        NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
        [thread start];
        * 直接启动
        a>.[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
        b>.[self performSelectorInBackground:@selector(run) withObject:nil];

      2> 其他用法
        NSThread *current = [NSThread currentThread]; // 获取当前线程
        + (NSThread *)mainThread; // 获得主线程
        + (void)exit; // 强制停止线程
        * 阻塞(暂停)线程
        + (void)sleepUntilDate:(NSDate *)date;
        + (void)sleepForTimeInterval:(NSTimeInterval)ti;

      3> 同步锁(互斥锁)
        1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,比如多个线程访问同一个对象、同一个变量、同一个文件,当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题
        同步锁的使用前提:多条线程抢夺同一块资源
        a>.同步锁使用格式
          @synchronized(锁对象) { // 需要锁定的代码 }
          注意:锁定1份代码只用1把锁,用多把锁是无效的
        b>.同步锁的优缺点
          优点:能有效防止因多线程抢夺资源造成的数据安全问题
          缺点:需要消耗大量的CPU资源
        c>.线程同步
          线程同步的意思是:多条线程按顺序地执行任务
          同步锁,就是使用了线程同步技术

      4> 线程间通信
        - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
        - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

    2.GCD(重点)
      1> GCD的优势
        GCD是苹果公司为多核的并行运算提出的解决方案
        GCD会自动利用更多的CPU内核(比如双核、四核)
        GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
        程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码
      2> 队列的类型
        * 并发队列
        获得全局的并发队列: dispatch_get_global_queue

        * 串行队列
        a.自己创建: dispatch_queue_create
        b.主队列: dispatch_get_main_queue
        并发和串行决定了任务的执行方式
        并发:多个任务并发(同时)执行
        串行:一个任务执行完毕后,再执行下一个任务
      3> 执行任务的方法类型
        * 同步(sync)执行
        * 异步(async)执行
        同步和异步决定了要不要开启新的线程
        同步:在当前线程中执行任务,不具备开启新线程的能力
        异步:在新的线程中执行任务,具备开启新线程的能力

      4> 线程间通信
        dispatch_async(
          dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
          // 执行耗时的异步操作...
          dispatch_async(dispatch_get_main_queue(), ^{
            // 回到主线程,执行UI刷新操作
          });
        });

      5> 其他用法
        dispatch_once // 用于单例对象
        dispatch_after // 延迟加载
        dispatch_group_asyncdispatch_group_notify // 队列组

    3.NSOperation
      1> 基本使用
        a>.NSInvocationOperation : - (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
        b>.NSBlockOperation : + (id)blockOperationWithBlock:(void (^)(void))block;
          - (void)addExecutionBlock:(void (^)(void))block; // 添加操作
          只要NSBlockOperation封装的操作数 > 1,就会异步执行操作

      2> NSOperationQueue(重点)
        *添加操作到NSOperationQueue中
        - (void)addOperation:(NSOperation *)op;
        - (void)addOperationWithBlock:(void (^)(void))block;
        * 最大并发数设置
        - (NSInteger)maxConcurrentOperationCount;
        - (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
        *取消队列的所有操作
        - (void)cancelAllOperations;
        提示:也可以调用NSOperation的- (void)cancel方法取消单个操作

        *暂停和恢复队列
        - (void)setSuspended:(BOOL)b; // YES代表暂停队列,NO代表恢复队列
        - (BOOL)isSuspended;

        * 设置依赖(面试题)
        [operationB addDependency:operationA]; // 操作B依赖于操作A

      3> 自定义Operation(了解基本流程)
        重写- (void)main方法,在里面实现想执行的任务
        重写- (void)main方法的注意点
        自己创建自动释放池(因为如果是异步操作,无法访问主线程的自动释放池)
        经常通过- (BOOL)isCancelled方法检测操作是否被取消,对取消做出响应

      4> 如何解决一张图片(一个url)重复下载的问题(面试题)
        使用字典或对象根据url保存下载的异步操作,判断这个异步操作是否存在,存在就不在创建

  • 相关阅读:
    【BZOJ】【1415】【NOI2005】聪聪和可可
    【ContestHunter】【弱省胡策】【Round5】
    【UOJ Round #8】
    【BZOJ】【2738】&【Tsinsen】【A1333】矩阵乘法
    【BZOJ】【2527】【POI2011】Meteors
    【ContestHunter】【弱省胡策】【Round4】
    【BZOJ】【3170】【TJOI2103】松鼠聚会
    【BZOJ】【2878】【NOI2012】迷失游乐园
    【BZOJ】【2434】【NOI2011】阿狸的打字机
    【BZOJ】【2435】【NOI2011】道路修建
  • 原文地址:https://www.cnblogs.com/wentianblog/p/3807123.html
Copyright © 2011-2022 走看看