一、为什么要多线程
通俗的讲,多线程可以理解为程序运行的时候齐头并进的效果。一般的java程序在主线程启动之后,cpu的资源就是单纯为这个主线程来准备的(除去垃圾回收线程和其他的守护线程外),而多线程就不一样了。因为线程和主线程之间在资源上是竞争关系,所以cpu的资源会被所有的线程共享。
有人可能会问,这样有什么用呢?
当然有用,这样可以充分利用cpu的使用率。由于现在的服务器都是多核cpu,某个cpu在处理一件事的时候,其他的cpu都是空闲的。既然如此,我们就可以使用多线程来利用这些空闲的cpu去做一些别的工作。
比如,我们三个人做饭,一般会分好工。“一个人负责蒸饭,第二个人负责处理食材,第三个人负责下厨。”这就是同一个运用程序的三个线程。
下面用图来说明一下区分多线程和单线程。
通过上面描述的例子,我画了一张简图,相信大家看了之后应该很明白多线程和单线程之间的区别了。两个程序都可以实现做饭,但明显多线程的所花费的时间会比单线程少(单线程需要1.5h,多线程只需要0.5h),这是因为资源利用上,多线程的方案由于单线程的原因。
可能有的同学又会说了,不对,三个人做饭,为什么不让三个人集中精力去,一件一件的做完呢,比如,一个人买菜需要0.5h,而三个人只需要0.5h/3的时间,以此类推,单线程的总共也只需要0.5/3*3=0.5h时间。这样看上去,单线程和多线程花的时间是一样的,没有任何区别了。
如下图:
没错,这样的设计看上去跟多线程所达到的效率也是一样的!!!
三个线程,三个步骤中,每一个步骤都是一起工作,到程序完毕以后,同样只需要0.5h!!
那么既然单线程的方式效率也可以达到预期,为什么可以还要使用多线程呢?
其实,真正的原因是因为随着计算机科学的发展,工业对计算机硬件的支持已经达不到要求了,上图的设计所要实现,必须依赖于cpu的主频非常高的要求。
大家学过计算机历史的人都知道著名的摩尔定律:计算机的芯片的性能,每隔十八个月将会提高一倍。
这意味着,在如今cpu主频已经到达4GHZ的基础上,在过一年半,CPU的主频就会到达8GHZ!
但实际上,世界上现有的芯片制造厂家如(著名的英特尔)目前根本无法突破5GHZ,摩尔定律失效了。不要说一年半以后,即便是五年以后,芯片主频也很难到达8GHZ!
如果说芯片主频无法再硬件上取得性能的突破,那么计算机在发展商就会遇到瓶颈。在这个背景下,科学家们不得不放弃芯片在硬件上的突破,从而试图在软件层面上去设计,使得计算机的发展能够依旧适应大数据时代的需求。
而这个解决方案就是多核cpu。
既然一个cpu无法满足需求,那就在服务器上安装多个cpu。让应用程序运行的时候,可以得到多个cpu的资源。既然要得到cpu的资源要同时得到运用,那么就应该启动多个线程去使用这些资源,线程间互不干扰,齐头并进,提高整体运行效率!!
回归到之前的做饭程序的话题。也就是说,随着时代的发展,cpu的主频在硬件上发展遇到了问题,可以看做是三个人一起去买菜,乍一看上去这件事完全没有问题,但实际上,这三个人可能性格不太匹配,一个喜欢斤斤计较,另一个又喜欢大手大脚,而第三个有可能有别的性格缺陷,从而导致买菜过程存在分歧,吵架,花费了时间在处理分歧上,原本预期中,只需要0.5/3h时间完成买菜,而实际上花费了0.4个小时,甚至超过了0.5h,以此类推,蒸饭和下厨也是一样的,这么下来,即便是三个人一起去做每个步骤,还是无法保证程序在0.5h内完成!!
但多线程不一样,它使得三个人独立工作,互补干扰(当然也可以实现通讯,跟业务场景相关),可以稳定的实现资源的合理分配。
二、进程和线程的关系
1、什么是进程,什么是线程?
进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。
一个程序至少一个进程,一个进程至少一个线程。
2、进程线程的区别
1、地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
2、资源拥有:同一进程内的线程共享本进程的资源,但是进程之间的资源是独立的。
3、一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
4、进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。
5、执行过程:每个独立的进程程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
6、线程是处理器调度的基本单位,但是进程不是。
7、两者均可并发执行。
8、进程是操作系统进行资源分配的基本单位,而线程是操作系统进行调度的基本单位,即CPU分配时间的单位。
3、优缺点:
线程执行开销小,但是不利于资源的管理和保护。线程适合在SMP机器(双CPU系统)上运行。
进程执行开销大,但是能够很好的进行资源管理和保护。进程可以跨机器前移。
4、什么地方会用到多线程?
1、后台线程:比如定期执行一些特殊任务,如定期更新配置文件,任务调度,一些监控用于定期信息采集等。
2、最典型的应用比如tomcat,tomcat内部采用的就是多线程,上百个客户端访问同一个web应用,tomcat接入后都是把后续的处理扔给一个新的线程来处理,这个新的线程最后调用到我们的servlet程序,比如doGet或者doPost方法。还有就是需要异步处理的时候,需要使用多线程。
3、特别耗时的操作,如备份数据库,可以开个线程执行备份,然后执行返回,前台不断向后台询问线程执行状态。