简介

前面讲解了 Java 中线程池 ThreadPoolExecutor 的原理,ThreadPoolExecutor 只是 Executors 工具类的一部分功能。下面来介绍另外一部分功能,也就是 ScheduledThreadPoolExecutor 的实现,这是一个可以在指定一定延迟时间后或者定时进行任务调度执行的线程池。

类图介绍

类图结构如图 9-1 所示。

Executors 其实是个工具类,它提供了好多静态方法,可根据用户的选择返回不同的线程池实例。ScheduledThreadPoolExecutor 继承了 ThreadPoolExecutor 并实现了 ScheduledExecutorService 接口。线程池队列是 DelayedWorkQueue,其和 DelayedQueue 类似,是一个延迟队列。

ScheduledFutureTask 是具有返回值的任务,继承自 FutureTask。FutureTask 的内部有一个变量 state 用来表示任务的状态,一开始状态为 NEW,所有状态为

  1. private static final int NEW = 0 //初始状态
  2. private static final int COMPLETING = 1 //执行中状态
  3. private static final int NORMAL = 2 //正常运行结束状态
  4. private static final int EXCEPTIONAL = 3 //运行中异常
  5. private static final int CANCELLED = 4 //任务被取消
  6. private static final int INTERRUPTING = 5 //任务正在被中断
  7. private static final int INTERRUPTED = 6 //任务已经被中断

介绍 - 图1

图 9-1
image.png

可能的任务状态转换路径为

  1. NEW -> COMPLETING -> NORMAL //初始状态-> 执行中-> 正常结束
  2. NEW -> COMPLETING -> EXCEPTIONAL//初始状态-> 执行中-> 执行异常
  3. NEW -> CANCELLED//初始状态-> 任务取消
  4. NEW -> INTERRUPTING -> INTERRUPTED//初始状态-> 被中断中-> 被中断

ScheduledFutureTask 内部还有一个变量 period 用来表示任务的类型,任务类型如下:

● period=0,说明当前任务是一次性的,执行完毕后就退出了。

● period 为负数,说明当前任务为 fixed-delay 任务,是固定延迟的定时可重复执行任务

● period 为正数,说明当前任务为 fixed-rate 任务,是固定频率的定时可重复执行任务

ScheduledThreadPoolExecutor 的一个构造函数如下,由该构造函数可知线程池队列是 DelayedWorkQueue。

  1. //使用改造后的 Delayqueue
  2. public ScheduledThreadPoolExecutorint corePoolSize {
  3. //调用父类 ThreadPoolExecutor 的构造函数
  4. supercorePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
  5. new DelayedWorkQueue());
  6. }
  7. public ThreadPoolExecutorint corePoolSize,
  8. int maximumPoolSize,
  9. long keepAliveTime,
  10. TimeUnit unit,
  11. BlockingQueue<Runnable> workQueue {
  12. thiscorePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
  13. Executors.defaultThreadFactory(), defaultHandler);
  14. }