一:什么是线程池
线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。
二:为什么要有线程池
1.避免了在处理短时间任务时创建与销毁线程的代价:
线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池护着多个线程,等待着监督管理者分配可并发执行的任务,保证内核的充分利用。
2. 防止过分调度:
可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。 例如,线程数一般取cpu数量+2比较合适,线程数过多会导致额外的线程切换开销。
三:线程池的实现原理
假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。
一般一个简单线程池至少包含下列组成部分。
1.线程池管理器(ThreadPoolManager):
2.用于创建并管理线程池
3工作线程(WorkThread): 线程池中线程
4.任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行。
5.任务队列:用于存放没有处理的任务。提供一种缓冲机制。
四:常见的线程池
-
线程池的返回值ExecutorService简介:
ExecutorService是Java提供的用于管理线程池的接口。该接口的两个作用:控制线程数量和重用线程
-
具体的4种常用的线程池实现如下:(返回值都是ExecutorService)
2.1 Executors.newCacheThreadPool():可缓存线程池,先查看池中有没有以前建立的线程,如果有,就直接使用。如果没有,就建一个新的线程加入池中,缓存型池子通常用于执行一些生存期很短的异步型任务
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();2.2 Executors.newFixedThreadPool(int n):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);2.3 Executors.newScheduledThreadPool(int n):创建一个定长线程池,支持定时及周期性任务执行
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);2.4 Executors.newSingleThreadExecutor():创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
参考与:https://www.jianshu.com/p/874dcc95c5c1
https://blog.youkuaiyun.com/hnd978142833/article/details/80253784