本篇将会简单介绍各种jdk自带的线程池,简单讲解线程池的源码(非常简单的介绍)
ThreadPoolExecutor
SingleThreadPool
根据源码,我们发现,SingleThreadPool 的核心线程数量和最大线程数量都是1,也就是说这个线程池里面只会有一个线程,因为没有非核心线程数,所以keepalive为0,它的任务队列是LinkedBlockingQueue
我们继续深入源码,发现它的线程工厂是 DefaultThreadFactory ,它的拒绝策略是 AbortPolicy
SingleThreadPool只有一个线程,它的用处是保证我们传入的任务是顺序执行的
CachedThreadPool
- 我们可以发现非常奇怪的地方,这个线程池的核心线程数为0,但是非核心线程数是 Integer.MAX_VALUE ,每一个线程的存活时间都是60s;这个线程的任务队列是SynchronousQueue,这个任务队列的size是0,也就是说,每当一个任务来的时候,它是无法加入任务队列的,这个任务会被阻塞住,一直等待一个线程来将任务取走
- 这个线程池的工作原理就是每当一个任务到来的时候,如果这个线程池中有空闲的线程,那么就将任务分配给这个线程,如果没有空闲的线程,那么就直接创建一个新的线程
- 这个线程池在极高并发情况下并不推荐使用,因为每来一个任务就会创建一个线程,如果当并发量极高,类似淘宝这种的话,那么就会产生大量的线程,这样cpu的性能就会被浪费在来回切换上面了,产生“过度切换”问题
FixedThreadPool
- 我们可以看到,每当我们要创建FixedThreadPool的时候,我们要传入一个参数,这个参数就是这个FixedThreadPool的核心线程数和最高线程数,也就是说,FixedThreadPool 的最大线程数是在一般情况下是固定的,并且全部是核心线程
- FixedThreadPool Vs CachedThreadPool
- 对于一个程序线程数量的分配是有公式的,但是这个公式很难计算,所以有的时候可以估算为计算机核心数 + 1(只是估算,必须要通过压测才可以确定最合适的核心数)
- FixedThreadPool比较适合于并发比较稳定的情况,请求在打来的时候是比较平稳的,不会忽极高忽极低这样就比较适合FixedThreadPool,因为我们可以通过压测,测试出这个水平线的并发请求多少个线程比较合适
- CachedThreadPool比较适合于请求的数量波动明显的情况,这样就可以动态地根据请求数量来确定线程数量
ScheduledThreadPool
- 这个线程池的核心就是DelayWorkQueue,所以这个线程池的作用就是每隔一段时间就执行一次任务
ForkJoinPool
WorkStealingPool
- WorkStealingPool没有太大好说的地方,这个线程池的特点是一个线程如果将自己任务队列里面的任务执行完毕后会从其他的线程的任务队列里面“偷”任务回来执行
文档信息
- 本文作者:JunHua yin
- 本文链接:https://yin-JH.github.io/2021/03/22/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E4%B8%8E%E9%AB%98%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E7%B3%BB%E5%88%97(%E5%85%AB)%E4%B9%8B%E5%90%84%E7%A7%8D%E7%BA%BF%E7%A8%8B%E6%B1%A0%E4%BB%8B%E7%BB%8D%E5%8F%8A%E6%BA%90%E7%A0%81%E7%AE%80%E5%8D%95%E8%A7%A3%E6%9E%90/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)