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

来源:互联网 发布:php开发实战教程 编辑:程序博客网 时间:2024/06/09 23:09

一.多线程的原理,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
原创粉丝点击