多线程必备宝典(持续更新)

一.多线程的原理,NSThread:


1.线程状态

1.1 线程状态运行过程

线程状态运行过程

1.2 线程状态解释

  1. 新建
    • 实例化线程对象
  2. 就绪

    • 向线程对象发送 start 消息(调用start方法),线程对象被加入可调度线程池,等待CPU调度
    • detachNewThreadSelector 方法和 performSelectorInBackground 方法会直接实例化一个线程对象,并加入到可调用线程池中,等待CPU的调度,不需要我们再去调用start方法
  3. 运行

    • CPU 负责调用可调度线程池中的线程
    • 线程完之前,状态会在就绪和运行之间来回切换,因为CPU不会执行完某个线程之后才去执行其他的线程
    • 就绪和运行之间的状态变化由CPU来决定,程序员无法干预
  4. 阻塞
    4.1. 当线程满足某些条件的时候,可以使用休眠或者锁阻塞线程的操作

    • sleepForTimeInterval 休眠指定时长
    • sleepUntilDate 休眠到指定日期
    • @synchronized(self) 互斥锁
  5. 死亡
    5.1. 正常死亡

    • 线程执行完成之后

    5.2. 非正常死亡

    • 当满足某个条件之后,在线程内部中止执行
    • 当满足某个条件之后,在其他线程中中止线程对象

2.线程安全

2.1 资源共享

  1. 生活中很多地方都存在线程资源共享的例子,比如:抢票,存钱

2.2 资源共享的影响

  1. 以下是在没有处理的情况下
  2. 在抢票分配痛苦过个中,造成两个人,甚至多个人购买同一张票
  3. 取钱过程中可能造成余额错误
  4. 抽奖活动造成多人中奖

2.3 解决办法 - 互斥锁

2.3.1 互斥锁介绍

  1. 语法
    @synchronized(self) { 
    }
    
  2. 作用
    保证同一段代码,在同一时间内,只能在一个线程里面执行。在第一个线程进来的时候会对代码进行上锁,而第一个线程执行完之后会把锁打开,这个时候别的线程才会进来执行代码。

  3. 影响
    效率变慢

  4. 注意点
    互斥锁里面应尽量放少的代码,把读写的代码放到锁里面即可
  5. 锁对象
    锁对象就是一个能加锁的NSObject 对象,锁一定是全局的,否则会锁不住,无法进行保存。一般情况下我们使用self 就当作锁对象即可

2.4 示例代码

  - (void)saleTicket {
      while (YES) {
          [NSThread sleepForTimeInterval:1.0];
          /**
           1. 互斥锁为了保证同一资源在同一时间内,只能在一线程里使用
           2. 别的线程想要使用同一个资源,必须等待另一个线程执行完成。完成后开锁了才可以使用
           3. 使用互斥锁会消耗更多资源
           */
          @synchronized(self) {
              if (self.ticket > 0) {
                  NSLog(@"%@--%zd",[NSThread currentThread],self.ticket);
                  self.ticket --;
                  continue;
              }
          }
          break;
      }
  }



二.GCD的概念

1.1 什么是GCD

Grand Central Dispatch (GCD) 是导步执行任务的技术之一。一般将应用程序中记述的线 程管理用的代码在系统级中实现。开发者只需要定义想执行的任务并追加到适当的 Dispatch Queue 中,GCD 就能生成必要的线程并计划执行任务。由于线程管理是作为系统的一部份 来实现,因为可统一管理,也可执行任务,就样就比以前的线程更有效率。
也就是说,GCD 用我们难以默念的非常的简洁的记述方法,实现了极为复杂繁琐的多 线程线程,可以说是一项目划时代的技术。

1.2 GCD的核心概念

  1. 将任务添加到队列,并且指定执行任务的函数
  2. 任务使用block封装,任务的block没有参数没有返回值
  3. 执行任务的函数
    3.1 异步 dispatch_async
     * 不用等待当前语句执行完毕,就可以执行下一个语句
     * 会开启线程执行block 任务
     * 异步是多线程的代名词
    
    3.2 同步 dispatch_sync
     * 必须等待当前语句执行完毕才可以执行下一条语句 
     * 不会开启线程
     * 在当前线程执行 block 任务
    
  4. 队列-负责调度任务
    4.1 串行队列

    * 一次只能执行一个任务  
    

    4.2 并发队列

     * 可同时执行多个任务  
    

    4.3 主队列

     * 专门用来在主线程上调度任务的队列
     * 不会开启线程,因为主线程是系统自动开启的
     * 在主线程**有空闲**的时候,才会调度队列中的任务
     * 如果当前是在主线程,不可以在同步函数中使用主队列,否则会造成一个死锁
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值