车驰夜幕|ThreadPoolExecutor线程池实现原理+源码解析

推荐学习

  • 被微服务轰炸?莫怕!耗时35天整出的「微服务学习教程」送你
  • 死磕「并发编程」100天 , 全靠阿里大牛的这份最全「高并发套餐」
  • 闭关28天 , 奉上[Java一线大厂高岗面试题解析合集] , 备战金九银十

车驰夜幕|ThreadPoolExecutor线程池实现原理+源码解析前言或许每个Java工程师都被问过这样一个问题
Java中开启一个新的线程有几种方法?
继承Thread类和实现Runnable接口 。 但是除了写Demo , 几乎没人会在生产环境上这样用 。 具体原因如下:
  • 线程频繁的被创建、销毁 , 非常消耗资源
  • 这两种方式开启的线程都不便于统一的调度和管理
  • HotSpot虚拟机采用1:1的模型来实现Java线程的 , 也就是说一个Java线程直接通过一个操作系统线程来实现 , 如果可以无限制的开启线程 , 很容易导致操作系统资源耗尽 。
线程池继承Thread和实现Runnable的诸多缺点 , 所以生产环境必须使用线程池来实现多线程 。
线程池(thread pool):一种线程使用模式 。 线程过多会带来调度开销 , 进而影响缓存局部性和整体性能 。 而线程池维护着多个线程 , 等待着监督管理者分配可并发执行的任务 。 这避免了在处理短时间任务时创建与销毁线程的代价 。 线程池不仅能够保证内核的充分利用 , 还能防止过分调度 。 可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量 。——维基百科
简单来说 , “池”在计算机领域是指集合 , 线程池就是指线程集合 。 线程池可以对一系列线程的生命周期进行统一的调度和管理 , 包括线程的创建、消亡、生存时间、数量控制等 。 Java中的线程池从JDK1.5开始 , 有一个标准的实现java.util.concurrent.ThreadPoolExecutor , 对于这个类 , 首先看下它的体系结构图
车驰夜幕|ThreadPoolExecutor线程池实现原理+源码解析
  • Executor:只定义了一个方法execute , 用于执行提交的任务
  • ExecutorService:定义了一些线程池管理、任务提交、线程池检测的方法
  • AbstractExecutorService:提供了ExecutorService接口执行方法的默认实现 , 用于统一处理Callable任务和Runnable任务
内部结构这里主要关注类的定义和一些重要的常量、成员变量
【车驰夜幕|ThreadPoolExecutor线程池实现原理+源码解析】public class ThreadPoolExecutor extends AbstractExecutorService { // 高3位表示线程池状态 , 低29位表示worker数量private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));// 29 = 32 - 3private static final int COUNT_BITS = Integer.SIZE - 3;// 线程池允许的最大线程数 。为 2^29 - 1private static final int CAPACITY= (1 << COUNT_BITS) - 1;// runState is stored in the high-order bits// 线程池有5种状态 , 按大小排序如下:RUNNING < SHUTDOWN < STOP < TIDYING < TERMINATEDprivate static final int RUNNING= -1 << COUNT_BITS;private static final int SHUTDOWN=0 << COUNT_BITS;private static final int STOP=1 << COUNT_BITS;private static final int TIDYING=2 << COUNT_BITS;private static final int TERMINATED =3 << COUNT_BITS;// Packing and unpacking ctl// 获取线程池状态private static int runStateOf(int c){ return c}// 获取线程池worker数量private static int workerCountOf(int c){ return c}// 根据线程池状态和worker数量生成ctl值private static int ctlOf(int rs, int wc) { return rs | wc; }// 缓冲队列(阻塞队列)private final BlockingQueue