- 介绍:进程指是正在运行的程序,也就是电脑或者手机上运行的应用。进程间互不干扰,2块不同的独立内存。线程是操作执行流程,每个进程至少要有一个线程。多线程主要体现一个多字,也就是进程内有多条线程。例子:进程就是一个工厂,线程就是工厂里面的流水线,多线程就是有多条流水线。在单核CPU下,多线程只是伪多线程,只是CPU快速的在它们之间来回切换进行操作;而在多核CPU下,就拥有了真正的独立执行力,有多少核心,就可以有多少真正的线程 ,而CPU的频率,就是线程的工作效率。在PC平台,有2大CPU大厂AMD和英特尔,而英特尔的CPU拥有超线程技术,就是每个CPU的核心,可以同时执行2条线程,这就是它为什么4核比AMD的8核还牛逼的原因。应用启动会自动帮我们启动一个线程,而这个线程我们称之为主线程,或者叫UI线程。它的作用就是显示刷新UI,处理UI事件的,如果耗时操作放到主线程,会照成界面的卡顿。
- 线程状态:
a) 新建:实例化线程对象
b) 就绪:向线程对象发送start消息,线程对象加入可调度线程池,等待CPU调度。
c) 运行:CPU调用可调度线程池中的线程。
d) 阻塞:当线程满足某些条件,可以使用休眠或阻塞线程的操作。(sleep、@synchronized(self))
e) 死亡:线程执行完成后,正常死亡;当满足某个条件后,在线程内部中结束或者在其他线程中结束另外线程 - 线程属性
a) 线程名字:可以看出是哪个线程
b) 栈区大小:默认是512Kb,因为线程里面也需要临时变量的存储
c) 线程优先级:0最低,1最高;优先级越高,调用频率越高。(一般不会修改) - 线程安全
a) 多个线程进行读写操作时,仍然能够得到正确的结果,被称为线程安全
b) 资源贡献的影响,比如在抢票分配中,可能存在多人购买同一张票。比如2条线程同时给一个属性赋值,这时就会照成可能崩溃。
c) 解决办法是互斥锁:@synchronized(self){};作用是同一时间内只能有一条线程在里面,这样做的影响就是效率会变慢,锁对象一般使用self就可以了,必须保证是全局的。
d) UI都是非线程安全的,因此所有的UI操作都必须在主线程执行。
e) 原子性和非原子性:原子性就是atomic是线程安全的,内部有一把自旋锁,写入单一,读取可以多线程。非原子性就是nonatomic非线程安全,效率高。
线程的技术方案

线程技术:GCD
- GCD(Grand Central Dispatch)是异步执行任务的技术之一,它是基于C语言的,只需要定义想执行的任务追加到合适的DispatchQueue中,GCD就能产生必要的线程并计划执行任务,完全由系统管理线程。
- 执行方式:(开不开线程于执行方式无关)
a) 异步执行dispatch_async:先进先出的方式执行任务。
b) 同步执行 dispatch_sync:异步不需要等待当前语句执行完,就可以往下执行其他的代码。 - 队列:负责调度任务(开不开线程与这个相关)
a) 串行队列:无论执行队列任务的方式是同步还是异步,都以先进先出的方式执行任务。串行队列最多只会开一条线程。串行队列&异步,最多只会开启一条线程,顺序执行任务。串行队列&同步的时候,不会开启线程,只在当前线程执行任务。
b) 并发队列:可以让多个任务同时执行,自动开启多个线程同时执行任务,并发功能只有在异步函数下才有效
c) 主队列:专门用来调度主线程任务的队列,不会开启线程,因为所有的任务都会在主线程执行,以先进先出的方式执行,在主线程有空闲的时候,才会调度队列中的任务,如果当前主线程在执行任务,那么主队列中被添加的任务,都不会被调度(配合异步操作,在视图初始化的时候,可以省略对生命周期的判断等)
i. 主队列&异步:主线程空闲的时候,执行主队列中的任务
ii. 主队列&同步:会照成死锁,主线程等待主队列,主队列又等待主线程,一直干等。
iii. 解决死锁的办法:使用并发队列同步执行主队列任务。
d) 全局队列:是系统为了方便程序员开发提供的,本质就是并发队列。跟并发队列的却别就是并发队列有名称,可以跟着错误信息,全局队列没有;无论在ARC和MRC情况下,全局队列都不需要手动管理内存,而并发队列在MRC下需要手动管理内存(释放内存)。 - barrier 异步:dispatch_barrier_async,使用barrier之后,所有的非线程安全对象的操作都会在最后在同一条线程中进行,这样就不会存在线程抢夺资源问题,也就不会造成程序闪退。必须使用创建的串行队列,不使用全局队列
- 一次性操作:dispatch_once,代码只运行一次。
- 调度组:在一组异步任务执行完毕之后,统一获得通知!
a) 创建调度组:dispatch_group_t group = dispatch_group_create();
b) 使用调度组异步函数进行异步操作:dispatch_group_async
c) 得到调度组执行任务完成通知:dispatch_group_notify - 延时操作:dispatch_after
线程技术:NSOperation
介绍:iOS除了GCD多线程技术外,还有NSOperation。NSOperation是一个抽象类,不能直接使用,使用它的子类:NSInvocationOperation、NSBlockOperation。NSOperation的核心概念是把操作添加到队列,所以还需要一个队列,NSOperationQueue。
-
抽象类:抽象类必须是子类继承它之后才可以实例化对象,抽象类的用处是定义子类共有的属性和方法,在苹果的头文的中,抽象类一般情况下和子类是同一个头文件中。已经学习过的抽象类还有: UICollectionViewLayout(布局对象)、UIGestureRecognizer(手势)、CAAnimation(动画)、CAPropertyAnimation(属性动画)。
-
NSInvocationOperation的使用:
a) 创建NSInvocationOperation对象:NSInvocationOperation *op =[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(demo)object:nil];
b) 创建队列NSOperationQueue *queue = [[NSOperationQueuealloc]init];
c) 把对象添加到队列:[queue addOperation:op]; // 开启线程异步执行
d) 注意:[op start]; 直接调用start 方法不会开启线程,在当前线程同步执行
- NSBlockOperation的使用
a) 创建NSBlockOperation对象:NSBlockOperation op = [NSBlockOperationblockOperationWithBlock:^{/操作代码*/};
b) 创建队列: NSOperationQueue *queue = [[NSOperationQueuealloc]init];
c) 把操作添加到队列: [queue addOperation:op];
d) 结论:直接通过block创建操作,使用方式跟GCD很相似
- NSOperation的其他功能:
a) NSOperationQueue 直接创建操作:[queueaddOperationWithBlock:^{/操作/}; //队列的操作
b) 获取主队列:[NSOperationQueue mainQueue]//队列的方法
c) 设置最大并发数:queue.maxConcurrentOperationCount= 2;//队列的属性
d) 暂停/继续:self.queue.suspended = !self.queue.isSuspended;self.queue.isSuspended;//队列的属性
e) 取消所有操作:[self.queuecancelAllOperations];//队列的操作
f) 操作间添加依赖(操作的方法):[op2addDependency:op1]; [op3 addDependency:op2]; [op4addDependency:op3]; //不要循环依赖
- NSOperation 与 GCD对比
a) GCD的简单说明
i. 将任务 block 添加到队列中,并指定执行的函数(同步/异步)
ii. GCD是底层C语言构成的API
iii. iOS4 推出的,针对多核心处理器的并发技术
iv. 在队列中执行的block 构成的任务,是一个轻量级的数据结构
v. 要停止已经加载队列中的任务,需要写复杂的代码
vi. 需要通过 Barrier 或者同步任务设置任务之间的依赖
vii. 只能设置队列的优先级
viii. 高强功能:一次性执行、延时执行、调度组
b) NSOperation的简单说明
i. 核心概念:把操作添加到队列
ii. OC写的框架,更加面向对象,是对GCD的封装
iii. iOS2 推出,苹果推出GCD之后,对NSOperation 的底层全部重写
iv. NSOperation 作为一个对象,为我们提供了更多的选择
v. 可以随时取消已经设置要准备执行的任务,已经执行的不能取消
vi. 可以跨队列设置操作的依赖
vii. 可以设置队列中第一个操作的优先级
viii. 高级功能:最大操作并发数,用于限制开线程数、继续/暂停/全部取消、跨队列设置操作的依赖
- 自定义NSOperation:
a) 自定义NSOperation继承于NSOperation。
b) 重写main方法,当队列调度操作执行时,会自动运行main方法,主要main方法中添加自动释放池。@autoreleasepool{}
网友评论