多线程,一直是解决内存暴增方法的重点,图片、视频、大量数据的的下载现在总结一下
基本概念
进程:应用程序的执行实例,简单来说就是在操作系统中运行的程序
线程:进程中负责程序执行的执行单元。一个进程中至少有一个线程。
多线程:解决多任务同时执行的需求,合理使用CPU资源。多线程的运行是根据CPU切换完成,如何切换由CPU决定,因此多线程运行具有不确定性。
线程池:基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
一、进程
1、进程是应用程序的执行实例,简单来说就是在操作系统中运行的程序。例如我在手机上只打开QQ和微信这两个软件,系统中就会有两个进程存在。它们互相是独立的。
2、进程不能执行任务。
3、进程在运行时创建的资源随着进程的终止而死亡。
二、线程池
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。----百度百科
对于iOS来说,建议在尽可能的情况下避免直接操作线程,使用比如NSOperationQueue这样的机制。
可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。
三、线程
1、进程本身是不能执行任务的,进程想要执行任务必须的有线程,线程是进程内部的一个独立的执行单元,同时只能执行一个任务,相当于一个子程序。线程被分为两种,主线程(用户界面线程)和子线程(工作线程或称为后台线程)。
2、线程执行完毕就会被销毁。
3、主线程(也称父线程)当应用程序启动时自动创建和启动,通常用来处理用户的输入并响应各种事件和消息。主线程的终止也意味着该程序的结束。
4、子线程:由主线程来创建,用来帮助主线程执行程序的后台处理任务。如果子线程A中又创建一个子线程B,在创建之后,这两者就是相互独立的,多个子线程之间效果上可以同时执行。
5、一个进程中可以有多个线程,并且所有线程都在该进程的虚拟地址空间中,可以使用进程的全局变量和系统资源。
6、线程的五种状态:
6.1 新建状态:线程对象已经创建,还没有在其上调用start()方法。
self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil];
6.2就绪状态:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态。当start()方法调用时,线程首先进入可运行状态。在线程运行之后或者从阻塞、等待或睡眠状态回来后,也返回到可运行状态。
[self.thread start];
6.3 运行状态:线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。
6.4 阻塞状态:这是线程有资格运行时它所处的状态。实际上这个三状态组合为一种,其共同点是:线程仍旧是活的,但是当前没有条件运行。换句话说,它是可运行的,但是如果某件事件出现,有可能返回到可运行状态。 (所谓阻塞状态是正在运行的线程没有运行结束,暂时让出CPU,这时其他处于就绪状态的线程就可以获得CPU时间,进入运行状态。)
(1)设置线程阻塞1,阻塞2秒
[NSThread sleepForTimeInterval:2.0];
(2)第二种设置线程阻塞2,以当前时间为基准阻塞4秒
NSDate *date=[NSDate dateWithTimeIntervalSinceNow:4.0];
[NSThread sleepUntilDate:date];
6.5 死亡状态:当线程的任务结束,发生异常,或者是强制退出这三种情况会导致线程的死亡。线程一旦死亡,就不能复生。线程死亡后,线程对象从内存中移除。
7、线程的串行
1个线程中任务的执行是串行的
如果要在1个线程中执行多个任务,那么只能一个一个地按顺序执行这些任务
也就是说,在同一时间内,1个线程只能执行1个任务
比如在1个线程中下载3个文件(分别是文件A、文件B、文件C)
四、多线程
1、多线程:1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务
2、多线程原理:
同一时间,CPU只能处理1条线程,只有1条线程在工作(执行)
多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换)
如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象。
思考:如果线程非常非常多,会发生什么情况?
CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源
每条线程被调度执行的频次会降低(线程的执行效率降低)——所以一般我们会控制线程的数量。
3、多线程的优缺点
多线程的优点
能适当提高程序的执行效率
能适当提高资源利用率(CPU、内存利用率)
多线程的缺点
开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能
线程越多,CPU在调度线程上的开销就越大
程序设计更加复杂:比如线程之间的通信、多线程的数据共享
4、多线程在iOS开发中的应用
主线程:一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”
主线程的主要作用:
显示\刷新UI界面
处理UI事件(比如点击事件、滚动事件、拖拽事件等)
** 附注:主线程的使用注意:别将比较耗时的操作放到主线程中。耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种“卡”的坏体验**
五、iOS中的多线程方案
分为4种,从最早的pthread到基于GCD的NSOperation.
1、pthread:(C语言,非常古老的一种多线程方法)开发中用的比较少
2、NSThread (OC语言,开发中用的也比较少,主要用于调试程序)
3、GCD (C语言,苹果进行了封装,开发中用的比较多)
4、NSOperation (基于GCD,开发中用的非常多)
其中3和4系统会自动进行内存管理。当然,用的最多的也是GCD和NSOperation
线程理解,可参照:http://mp.weixin.qq.com/s?__biz=MjM5NzA1MTcyMA==&mid=403498894&idx=2&sn=219c1a6001b5bb7e6bdc7963b1af8450&scene=2&srcid=0330UDNmQ2GlTOLo1CY8IZfH&from=timeline&isappinstalled=0#wechat_redirect
参考来源:
http://blog.csdn.net/peter_teng/article/details/10197785
http://www.cnblogs.com/wendingding/p/3807184.html
http://www.cnblogs.com/wendingding/p/3805088.html