privatefinalAtomicIntegerctl=newAtomicInteger(ctlOf(RUNNING,0));ctl这个AtomicInteger类型 , 是对线程池的运行状态和线程池中有效线程的数量进行控制的一个字段 , 它同时包含两部分的信息:线程池的运行状态 (runState) 和线程池内有效线程的数量 (workerCount) , 高3位保存runState , 低29位保存workerCount , 两个变量之间互不干扰 。用一个变量去存储两个值 , 可避免在做相关决策时 , 出现不一致的情况 , 不必为了维护两者的一致 , 而占用锁资源 。通过阅读线程池源代码也可以发现 , 经常出现要同时判断线程池运行状态和线程数量的情况 。线程池也提供了若干方法去供用户获得线程池当前的运行状态、线程个数 。这里都使用的是位运算的方式 , 相比于基本运算 , 速度也会快很多 。
关于内部封装的获取生命周期状态、获取线程池线程数量的计算方法如以下代码所示:
privatestaticintrunStateOf(intc){returnc&~CAPACITY;}//计算当前运行状态privatestaticintworkerCountOf(intc){returnc&CAPACITY;}//计算当前线程数量privatestaticintctlOf(intrs,intwc){returnrs|wc;}//通过状态和线程数生成ctlThreadPoolExecutor的运行状态有5种 , 分别为:

其生命周期转换如下入所示:

图3 线程池生命周期
【java的线程池有几种 java线程的创建方式】2.3 任务执行机制
2.3.1 任务调度
任务调度是线程池的主要入口 , 当用户提交了一个任务 , 接下来这个任务将如何执行都是由这个阶段决定的 。了解这部分就相当于了解了线程池的核心运行机制 。
首先 , 所有任务的调度都是由execute方法完成的 , 这部分完成的工作是:检查现在线程池的运行状态、运行线程数、运行策略 , 决定接下来执行的流程 , 是直接申请线程执行 , 或是缓冲到队列中执行 , 亦或是直接拒绝该任务 。其执行过程如下:
- 首先检测线程池运行状态 , 如果不是RUNNING , 则直接拒绝 , 线程池要保证在RUNNING的状态下执行任务 。
- 如果workerCount < corePoolSize , 则创建并启动一个线程来执行新提交的任务 。
- 如果workerCount >= corePoolSize , 且线程池内的阻塞队列未满 , 则将任务添加到该阻塞队列中 。
- 如果workerCount >= corePoolSize && workerCount < maximumPoolSize , 且线程池内的阻塞队列已满 , 则创建并启动一个线程来执行新提交的任务 。
- 如果workerCount >= maximumPoolSize , 并且线程池内的阻塞队列已满, 则根据拒绝策略来处理该任务, 默认的处理方式是直接抛异常 。

图4 任务调度流程
2.3.2 任务缓冲
任务缓冲模块是线程池能够管理任务的核心部分 。线程池的本质是对任务和线程的管理 , 而做到这一点最关键的思想就是将任务和线程两者解耦 , 不让两者直接关联 , 才可以做后续的分配工作 。线程池中是以生产者消费者模式 , 通过一个阻塞队列来实现的 。阻塞队列缓存任务 , 工作线程从阻塞队列中获取任务 。
推荐阅读
- cad卸载工具怎么用 cad卸载干净的教程
- qq营销工具源码 最有效推广的方式
- 目前三防手机哪个好 最好的三防手机品牌
- 哪些人不宜喝酒
- 艾灸真的可以治疗哮喘吗
- 面包硬的其他原因
- 钓鲈鱼的饵料比较好用的有哪些
- 黄皮果的食用方法
- 骨盆前倾该怎么练呢
- 骨盆前倾是怎么形成的呢
