首先讲一下关于线程的基础知识。
1.什么是进程?
进程是指在系统中正在运行的一个应用程序
每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内。
2.什么是线程?
1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程)线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行。
4.多线程的原理。
同一时间,CPU只能处理1条线程,只有1条线程在工作(执行)多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换)如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象思考:如果线程非常非常多,会发生什么情况?CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源每条线程被调度执行的频次会降低(线程的执行效率降低)
4.多线程的优缺点。
多线程的优点
能适当提高程序的执行效率
能适当提高资源利用率(CPU、内存利用率)
多线程的缺点
开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能
线程越多,CPU在调度线程上的开销就越大
程序设计更加复杂:比如线程之间的通信、多线程的数据共享
6.线程中的属性。
线程中有4个最主要的名词。
- 同步任务:同步:在当前线程中执行任务,不具备开启新线程的能力。
- 异步任务:在新的线程中执行任务,具备开启新线程的能力。
并发和串行决定了任务的执行方式 - 并发队列:多个任务并发(同时)执行。
- 串行队列:一个任务执行完毕后,再执行下一个任务。
而主队列是特殊的串行队列。
全局队列是特殊的并发队列。
7.GCD的基础使用。
1.串行队列。
- 使用dispatch_queue_create函数创建串行队列
// 队列名称, 队列属性,一般用NULL即可
dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
- 使用 使用主队列(跟主线程相关联的队列)
主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行
使用dispatch_get_main_queue()获得主队列
2.并发队列。
GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建
使用dispatch_get_global_queue函数获得全局的并发队列
// 此参数暂时无用,用0即可。
dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority,unsigned long flags);
GCD 小结:
其实多线程就是在多个线程之间快速做“切换”的操作(在线程调度池里执行任务)。
线程里有个属性是优先级。这个属性决定的是线程有更多的机会去调用。并不是决定任务的先后顺序。
而且注意!!!!开发中 一定不要取修改优先级。否则会出现很多你想不到的错误。
不能把同步任务加入到主队列中。否则会出现同步锁现象。
8.NSoperation的基础使用。
- 并发数
(1)并发数:同时执⾏行的任务数.比如,同时开3个线程执行3个任务,并发数就是3
(2)最大并发数:同一时间最多只能执行的任务的个数。
(3)最⼤大并发数的相关⽅方法
-(NSInteger)maxConcurrentOperationCount;- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
说明:如果没有设置最大并发数,那么并发的个数是由系统内存和CPU决定的,可能内存多久开多一点,内存少就开少一点。
注意:num的值并不代表线程的个数,仅仅代表线程的ID。
提示:最大并发数不要乱写(5以内),不要开太多,一般以2~3为宜,因为虽然任务是在子线程进行处理的,但是cpu处理这些过多的子线程可能会影响UI,让UI变卡。
- 队列的取消,暂停和恢复
1)取消队列的所有操作
- (void)cancelAllOperations;
提⽰:也可以调用NSOperation的- (void)cancel⽅法取消单个操作
(2)暂停和恢复队列
-(void)setSuspended:(BOOL)b; // YES代表暂停队列,NO代表恢复队列
-(BOOL)isSuspended; //当前状态
(3)暂停和恢复的适用场合:在tableview界面,开线程下载远程的网络界面,对UI会有影响,使用户体验变差。那么这种情况,就可以设置在用户操作UI(如滚动屏幕)的时候,暂停队列(不是取消队列),停止滚动的时候,恢复队列。
NSOperation 小结:
GCD和NSOperation 都各有各的好处。
GCD能够开多个线程 但是并不能管理。
但是NSOperation 可以管理线程。还可以设置最大操作并发数。
而GCD可以使用延时方法 after 和sleep 还有一次性once方法 创建单例对象。
根据你所需要的去选择恰当的方法。
网友评论