OC底层原理

多线程(一)

2020-02-22  本文已影响0人  只写Bug程序猿

进程

进程通俗来说就是系统中正在运行的一个应用程序
每个进程之间是独立的每个进程均运行在其专用的切受保护的内存
ios开发中是单进程的,这样可以保证每个进程互不干扰,有单独的沙盒控件,这样更加安全,更加流畅
安卓是可以实现多进程的.

线程

线程是进程的基本执行单元,一个进程的所有任务都在线程中执行
进程想要执行任务必须有线程,进程中至少有一个线程
程序启动会默认开启一条线程,就是主线程或者UI线程

线程与进程的区别

  1. 地址空间: 同一个进程的线程共享本进程的地址控件,而进程之间是独立的地址控件
  2. 资源拥有: 同一个进程的线程共享本进程的资源,如内存,I/O,cpu等,但是进程之间的资源是独立的
  3. 一个进程奔溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃户导致整个进程都死掉,所以多进程比多线程更加健壮
  4. 进程切换时,消耗资源大,效率高. 所以设计到频繁的切换时,使用线程要好于进程,同样如果要求同时进行并且又要共享某些变量的并发操作,只能使用线程不能用进程
  5. 执行过程: 每个独立的进程有一个程序运行入口,顺序执行序列. 但是线程不能独立执行,必须依赖于应用程序,有应用程序提供多个线程执行控制
  6. 线程是cpu调度的基本单位,但进程不是

多线程的优缺点

优点
  1. 能适当提高程序的执行效率
  2. 能适当提高资源利用率(cpu,内存)
  3. 线程上的任务执行完成后,线程会自动销毁
缺点
  1. 开启线程需要占用一定的内存空间(默认情况下,每个线程都占512KB)
  2. 如果开启大量的线程,会占用大量的内存空间,降低程序性能
  3. 线程越多,CPU在调用线程上的开销越大
  4. 程序设计更加复杂,比如线程间的通讯,多线程的数据共享

多线程的原理

cpu在单位时间内快速的在各个线程之间切换

多线程的生命周期

  1. 新建: 新建线程
  2. 就绪 : start之后就会runnable,然后等待cpu分配资源,进行调用
  3. running : 当获得cpu调度之后就会到running状态
  4. 阻塞 : 当线程中任务异常是,比如sleep,或者死锁等操作之后就会造成线程阻塞.当阻塞解除之后不会直接到running状态而是又到就绪状态
  5. 死亡 : 任务执行完成或者强制退出


    多线程生命周期

线程池

线程池是多线程处理的一种形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池中的线程都是后台线程。每个线程都有默认的堆栈大小,以默认的优先级运行,并处在多线程单元中。

执行流程
  1. 判断线程池大小是否小核心线程池大小
  2. 如果小于.创建线程执行任务
    2.1 如果不小于 判断工作队列是否已满,不满,将任务提交到工作对垒,创建线程执行任务,如果已满,判断线程是否都在工作,如果都在工作交个饱和策略,如果没满创建线程执行任务
线程池执行流程

饱和策略

  1. AbortPolicy 直接抛出RejectedExecutionExeception异常阻止系统正常运行
  2. CallerRunsPolicy 将任务回退给调用者
  3. DisOldestPolicy 丢掉等待最久的任务
  4. DisCardPolicy 直接丢弃任务

这四种执行策略均实现了RejectedExecutionExeception接口。

线程与RunLoop的关系

  1. RunLoop与线程是一一对应关系,一个RunLoop对应一个核心线程,为什么说核心线程呢,因为RunLoop是可以嵌套的,但是核心的只能有一个,他们的关系保存在一个全局字典中
  2. runloop是来管理线程的,当线程的runloop被开启后,线程会在执行完成任务后进入休眠状态,有任务了会被唤醒去执行任务
  3. runloop 在第一次获取时被创建,在线程结束是销毁
  4. 对主线程来说,runloop在程序一启动就默认创建好了
  5. 对子线程来说,runloop死懒加载的,只有当我们使用的时候才会创建,所以在子线程用定时器要注意:确保子线程的runloop被创建,不然定时器不会回调

atomic与nonatomic 的区别

nonatomic非原子属性 非线程安全,适合内存小的移动设备
atomic 原子属性(线程安全),针对多线程设计的,是个默认值 消耗大量的资源
atomic 保证同一时间只有一个线程能够写入(但是同一个时间多个线程都可以取值)
atomic 本身就是一把锁(自旋锁)
atomic 单写多读:单个线程写入,多个程序读取

开发建议:
所有属性都生命为nonatomic
尽量避免多线程抢夺同一块资源
尽量将加锁,资源抢夺的业务逻辑交个服务器处理,减小移动客户端的压力

上一篇 下一篇

猜你喜欢

热点阅读