IOS多线程
基本概念
- 进程: 一个具有一定独立功能的程序关于某个数据集合的一次运行活动。可以理解成一个运行中的应用程序。
- 线程:*** 程序执行流的最小单元,线程是进程中的一个实体***。
- 同步: 只能在当前线程按先后顺序依次执行,不开启新线程。
- 异步: 可以在当前线程开启多个新线程执行,可不按顺序执行。
- 队列: 装载线程任务的队形结构。
- 并发: 线程执行可以同时一起进行执行。
- 串行: 线程执行只能依次逐一先后有序的执行。
一个进程可以有多个线程,也可以有多个队列
线程种类
-
Pthread
pthread
是一套C语言
的多线程API
。
1)优点:能够跨平台/可移植 能够在UNIX/LINX/Windows
下运行 。
2)缺点:使用难度比较大, 需要程序员手动管理线程的生命周期 。 -
NSThread
是一套OC框架, 基于对Pthread的封装,具有面相对象特性。
1)优点:NSThread 轻量级最低,相对简单。
2)缺点:手动管理所有的线程活动,如生命周期、线程同步、睡眠等。 -
GCD
Grand Central Dispatch (GCD)
是Apple
开发的一个多核编程的解决方法。旨在代替NSThread
多线程技术,充分利用设备的多核。也是一套基于C语言的API 不需要程序员手动管理线程的声明周期 。
1)优点:最高效,避开并发陷阱。
2)缺点:基于C实现(不算缺点,我挺喜欢用的)。 -
NSOperation
是一套OC
的API
,是对GCD
的封装 使用更加面向对象 , 不需要程序员手动管理线程的声明周期。 -
先将需要执行的操作封装到一个
NSOperation
对象中 -
然后将
NSOperation
对象添加到NSOperationQueue
中 -
系统会自动将
NSOperationQueue
中的NSOperation
取出来 -
将取出的
NSOperation
封装的操作放到一条新线程中执。
●NSOperation
是个抽象类,并不具备封装操作的能力,必须使用它的子类
● 使用NSOperation
子类的⽅方式有3种
●NSInvocationOperation
,NSBlockOperation
,自定义子类继承NSOperation
,实现内部相应的方法。
1)优点:自带线程周期管理,操作上可更注重自己逻辑。
2)缺点:面向对象的抽象类,只能实现它或者使用它定义好的两个子类:NSInvocationOperation
和NSBlockOperation
。
NSInvocationOperation:
创建NSInvocationOperation对象
- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
● 调用start
方法开始执行操作- (void)start
; 一旦执行操作,就会调用target
的sel
方法
● 默认情况下,调用了start
方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作
● 只有将NSOperation
放到⼀一个NSOperationQueue
中,才会异步执⾏行操作。
多线程概念
1个进程中可以开启多条线程,每条线程可以并发(同时:并非真正意义上得同时)执行不同的任务。
多线程技术解决了在同一条线程中执行多个任务的需要等待问题,多线程可以将多任务分配不同的线程,减少单线程执行多任务的负担,使得一条线程执行一个任务。
多线程并发执行的概念:
因为同一时间内,cpu只能处理1条线程,只有一条线程在执行任务。
其实多线程并发执行的实质,是cup快速地在多线程之间调度.
因为cpu调度的线程的速度非常快,就造成了多线程并发执行的假象
但是注意点:
如果在进程中开辟的线程非常多,cup会在众多的线程中进行频繁调度,会使得cpu累死,消耗大量的cup资源。而且 会使得每个线程被调度执
行的频次会降低,完成单个线程的任务的时间就会被延续的更长,线程的执行效率大幅度降低,所以我们规定在一个进程中,开辟的分线程数不要超过五个。
多线程的优缺点:
优点:能够适当提高程序的执行效率,能够适当提高资源的利用率;
缺点: 开启线程需要占⽤一定的内存空间(默认情况下,主线程占⽤用1M,⼦子线程占用512KB),如果开启⼤大量的线程,会占⽤用⼤大量的内存空间,降低程序的性能。线程越多,CPU在调度线程上的开销就越⼤大。
多线程中主线程的概念
一个iOS程序运行后,会默认开启1条线程,成为“主线程”或“UI线程”;
主线程的作用:显示和刷新UI界面,处理UI事件(点击事件,滚动事件,拖拽事件)。
主线程的使用注意:
不要将比较耗时的操作放在主线程中:耗时操作会卡住线程,严重影响UI的流畅度,给用户一种“卡”的坏体验。
多线程的安全隐患
资源共享:一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源;比如多线程访问同一个对象,同一个变量,同一个文件;
就是在多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题;
安全隐患的解决——互斥锁与自旋锁
互斥锁的使用格式:@synchronized(Object){//需要锁定的代码}
,互斥锁使用的是线程同步技术,在锁定的时候,其他线程处于睡眠状态,等待条件满足,再被唤醒。
互斥锁的优缺点:
- 优点:能够有效的防止因多线程抢夺资源造成的数据安全问题。
- 缺点:需要消耗大量的
CPU
资源。
自旋锁;在锁定的时候,其他线程会做死循环,一直等待这个条件满足,一旦条件满足立马执行。
多线程中锁的应用
- OC中定义属性有
nonatomic
和atomic
两种。atomic
是原子性,为setter
方法加锁。nonatomic
是非原子性的,不需要为setter
方法加锁。