1.多线程代码总结+Demo
https://www.jianshu.com/p/7649fad15cdb
多线程的基本概念
线程的状态与生命周期
多线程的四种解决方案:pthread,NSThread,GCD,NSOperation
线程安全问题
NSThread的使用
GCD的理解与使用
NSOperation的理解与使用
2 多线程应用场景
http://blog.csdn.net/loving_ios/article/details/48660703
3 多线程面试题
https://www.jianshu.com/p/1eecfca332f3
https://www.jianshu.com/p/266bec7c4dd2
我对多线程的理解:
①线程:代码的执行流;对应于代码,可以理解为一个任务。
②队列:分为串行队列和并发队列,串行:任务按照顺序一个一个执行;并发:通过CPU的快速切换,多个任务并发执行。
③方式:同步和异步。同步:一个接着一个,前一个没有执行完,后面不能执行,不开线程。异步:任务同一时间可以一起执行。
④三者关系?
将任务(要在线程中执行的操作block)添加到队列(自己创建或使用全局并发队列),并且指定执行任务的方式(异步dispatch_async,同步dispatch_sync)
队列:装载线程任务的队形结构。(系统以先进先出的方式调度队列中的任务执行)
GCD栅栏barrier
使用栅栏函数时,使用全局并发队列是无效的,只有使用create创建的并发队列才有效
当任务需要异步进行,但是这些任务需要分成两组来执行,第一组完成之后才能进行第二组的操作。这时候就用了到GCD的栅栏方法dispatch_barrier_async。
GCD队列组group+notify
异步执行几个耗时操作,当这几个操作都完成之后再回到主线程进行操作,就可以用到队列组了。
队列组有下面几个特点:
所有的任务会并发的执行(不按序)。
所有的异步函数都添加到队列中,然后再纳入队列组的监听范围。
使用dispatch_group_notify函数,来监听上面的任务是否完成,如果完成, 就会调用这个方法。
NSOperation的操作依赖
NSOperation有一个非常好用的方法,就是操作依赖。可以从字面意思理解:某一个操作(operation2)依赖于另一个操作(operation1),只有当operation1执行完毕,才能执行operation2,这时,就是操作依赖大显身手的时候了。
项目中一般在哪用到多线程?
多线程一般用于耗时操作,如:
网络请求
上传,下载文件
读取数据库
文件操作
大循环
什么是线程安全问题?有什么解决方案?
定义
多个线程同时访问同一块资源(例如同一个对象、变量、文件)时,引发的数据错乱和数据安全问题,称为线程安全问题
解决方法
添加互斥锁
互斥锁的使用格式 :@synchronized( 锁对象 ){ //需要锁定的代码}
加锁的原理:
使线程同步执行
使用互斥锁的注意事项:
锁对象必须是全局唯一的,一般用self
加锁必须满足多个线程共享同一块资源的前提条件
加锁需要耗费大量CPU资源
锁定一段代码只需要用一把锁
如何处理GCD造成的死锁问题
将队列改为非主队列
将调度方式改为异步调度
NSOperation和GCD的区别?
GCD不支持异步操作之间的依赖关系设置。如果某个操作的依赖另一个操作的数据(生产者-消费者模型是其中之一),使用NSOperationQueue能够按照正确的顺序执行操作。GCD则没有内建的依赖关系支持。
NSOperationQueue支持KVO,可以监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld)
实现机制的区别
GCD底层是基于C语言的,NSOperation则是对GCD的封装,是面向对象的
NSOperation只有两种类型的队列
主队列和非主队列(非主队列既可以是并行的也可以是串行的,默认是并行的)
GCD拥有四种类型的队列 (main, global, create[serial], create[concurrent] )
使用上的区别
GCD的使用更轻量级,而NSOperation作为对象提供了更丰富的API
在NSOperationQueue中,可以随时取消要准备执行的任务,而GCD没法停止已经加入queue的block中的任务
NSOperation通过继承,可以提高代码的复用度,这比GCD更有自由度和扩展性
同一个并行队列中的任务执行时,我们能够设置NSOperation的priority(优先级),使之按顺序执行,而在GCD中,要使block中的任务实现这个功能,需要大量复杂代码
实现多线程的方法:
NSObject的类方法 // -(void)performSelectornBackground/OnMainThread:(SEL)aSelector withObject:(id)arg
NSThread
NSOperation
GCD
“同步”和”异步”的区别:
"同步": 只能在'当前'线程中执行任务,不具备开启新线程的能力.
"异步": 可以在'新'的线程中执行任务,具备开启新线程的能力.
各个队列的执行效果:
串行队列同步执行,既在当前线程中顺序执行
串行队列异步执行,开辟一条新的线程,在该线程中顺序执行
并行队列同步执行,不开辟线程,在当前线程中顺序执行
并行队列异步执行,开辟多个新的线程,并且线程会重用,无序执行
主队列异步执行,不开辟新的线程,顺序执行
主队列同步执行,会造成死锁('主线程'和'主队列'相互等待,卡住主线程)
GCD的queue、main queue中执行的代码一定是在main thread么?
• 对于queue中所执行的代码不一定在main thread中。如果queue是在主线程中创建的,那么所执行的代码就是在主线程中执行。如果是在子线程中创建的,那么就不会在main thread中执行。
• 对于main queue就是在主线程中的,因此一定会在主线程中执行。获取main queue就可以了,不需要我们创建,获取方式通过调用方法dispatchgetmain_queue来获取。