up:: 线程池部分内容概述
说明:
(1) 本篇博客的内容:简单介绍线程池;
一:什么是“池”?
需要的时候可以快速使用,不用重新收集;
比如“人才池”:如果面试没通过,就可能会被放在人才池中;企业后面再想录取这个人的时候,就可以快速从人才池中获取,不用重新收集;
再比如“蓄水池”:下雨的时候,可以把雨水收集到蓄水池;等到干旱需要用水的时候,就可以快速从蓄水池中获取,不用重新收集;
“线程池”也是同理,我们会提前准备好一些线程;等到需要用到线程的时候,就可以快速从线程池中获取,而不用重新现创建了;
二:为什么要使用线程池?:如果不使用线程池的情况;
(1)我们每需要一个任务时,都要新开一个线程,去应对这个任务;比如;
(2)那么,我们执行10个任务时(注意,是执行10个,而不是执行10次),就需要开10个线程,去应对这个需求;比如;
(3)但是,如果我们要1000个任务呐?:如果没有线程池的话,我们就需要创建1000个线程,去应对这个需求;
虽然,创建1000个线程,能够满足这个需求;但是,这种做法笨笨的,不太好;主要是因为,对于Java语言来说,每个Java中的线程都会直接对应到操作系统中的一个线程;上面的做法,就相当于在操作系统中创建了1000个线程;而,这会带来很大的开销;这是因为,线程生命周期的开销是很高的,线程的创建和销毁需要JVM和操作系统提供一些辅助操作;即,在大量的线程的创建时,会消耗很多资源(尤其是内存);同时,线程销毁回收时,也会给垃圾回收器带来压力;并且,系统所能创建的线程数量是有上限的;比如,有个需求需要我们创建30万个任务,那么我们就只能傻乎乎的创建30万个线程吗?而,这很可能会超过系统所能创建线程数量的上限,导致程序报OOM内存溢出异常等;
(4)所以,不使用线程池的话,会有这些问题;
● 如果不使用线程池,可以归纳两个主要问题:(1)反复创建线程开销大;(2)过多的线程会占用太多的内存;
● 有两个解决问题的思路:(1)用少量的线程,以避免内存占用过多;(2)让部分线程都保持工作,且可以重复执行任务,以避免生命周期的损耗;
● 由此,就引出了线程池;
三:线程池;
1.线程池的好处;
(1) 使用线程池后,对于线程来说,我们不再需要反复的创建和收回了;而且,我们也消除了创建线程带来的延迟;结果就是,响应速度更快了;
(2) 使用线程池后,可以更加合理的统筹安排,合理利用CPU和内存;
● CPU和内存的是有限的;
● 根据CPU和内存的现状,灵活的调整线程的数量,以使得【线程不会太多,导致内存溢出】,【线程也不会太少,浪费CPU和内存资源】;即,我们可以通过线程池,灵活的掌控线程的数量,以达到一个平衡;
(3) 使用线程池后,可以统一管理资源;
● 比如,我们有很多任务时,需要有一个统一的管理器,来管理这些任务;
● 比如,有3000个任务执行到一半,我们不想执行了:如果我们使用了线程池的话,就可以统一的去操作;
● 使用线程池,也方便数据统计;
2.线程池的适用场景;
(1) 批量计算任务;
● 比如,我们有大量的数据需要计算;而且,计算的过程又比较复杂(比如,需要读取数据库,需要做密集运算),此时就适合使用线程池;(如果我们不使用线程池,也不用多线程,而是使用单线程去跑大量的数据,其效率是比较低的)
(2) 服务器处理请求;
● 已知,服务器是可以同时处理多个请求的;
● 为了能够实现这个,就可以使用线程池去支持;
(3) Excel解析;
● Excel一般是多行的;此时,如果使用一个线程,去一行一行的解析,速度将会很慢;
● 如果,我们把每一行看成是一个独立的任务,利用线程池去处理,速度将会大幅提升;
在实际开发中,如果需要创建5及以上的线程时,那么就可以考虑使用线程池来管理;