什么是线程池
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。【来自于百度百科】
为什么需要用到线程池
通过上面线程池的简介,我们其实可以发现,普通的创建一个线程都是及创及用,并且没有上线,我想创建1000个线程或者创建10000个线程都可以,但是这样创建线程的方式有一个问题,那就是忽略了执行环境的性能,比如我们平时一个64位4核的服务器,他建议的线程数可以由公示算出来
线程池大小 = (物理CPU数量 x CPU核数) + 1
如何获取linux服务器逻辑CPU个数可以使用下面这个命令
逻辑CPU个数,使用命令: cat /proc/cpuinfo | grep 'processor' | wc -l
物理CPU个数,使用命令: cat /proc/cpuinfo | grep 'physical id' | sort | uniq | wc -l
这里例如我这里4核的服务器,逻辑CUP个数是4个,那么他的建议线程池大小为17个。相对于10000个线程是远远不够的,如果我们创建普通的线程远远大于17个线程,那么就会给服务器的CPU线程造成很大的开销,甚至会让多线程执行变得还没有单线程执行的快。
那么线程池的作用就显示出来了,他就是为了去控制线程执行的上线,同时也会给线程保持活跃性,比如10000个线程在线程中执行,他会先执行17个线程,声线的9983个线程就会在线程的队列中等待,等到之前17个线程中有执行完毕的线程让出了位置,这是后面排队的线程才可以继续补上执行,这样就最大限度的保证了cup执行线程最大的性能。减少了CUP很多的调度开销。当当前没有17个线程执行的时候,线程池也会创建辅助线程放在线程池中,来保持17个线程的活跃性,这让下次来了新的线程,线程池就减少了创建线程的开销,直接开箱即用。这就是为什么需要使用线程池的目的。
使用线程的好处
- 线程池可以解决线程生命周期的系统开销问题,同时还可以加快响应速度。因为线程池中的线程是可以复用的,我们只用少量的线程去执行大量的任务,这就大大减小了线程生命周期的开销。而且线程通常不是等接到任务后再临时创建,而是已经创建好时刻准备执行任务,这样就消除了线程创建所带来的延迟,提升了响应速度,增强了用户体验。
- 线程池可以统筹内存和 CPU 的使用,避免资源使用不当。线程池会根据配置和任务数量灵活地控制线程数量,不够的时候就创建,太多的时候就回收,避免线程过多导致内存溢出,或线程太少导致 CPU 资源浪费,达到了一个完美的平衡。
- 线程池可以统一管理资源。比如线程池可以统一管理任务队列和线程,可以统一开始或结束任务,比单个线程逐一处理任务要更方便、更易于管理,同时也有利于数据统计,比如我们可以很方便地统计出已经执行过的任务的数量。