JDK
版本:AdoptOpenJDK 11.0.10+9
1 基本概念
ScheduledThreadPoolExecutor
是j.u.c
内置的用于处理延时、周期性任务调度的线程池。它继承了ThreadPoolExecutor
类同时实现了ScheduledExecutorService
接口。
- 由于要满足任务的延时、周期调度,在
ScheduledThreadPoolExecutor
中会对所有Runnable
任务进行包装,包装成一个RunnableScheduledFuture
任务。
ScheduledThreadPoolExecutor
中的任务队列是一种特殊的延时队列 ——DelayedWorkQueue
。底层基于 “堆” 结构实现,能够保证每次从队列获取的任务都是最先到期的任务。
static class DelayedWorkQueue extends AbstractQueue<Runnable>
implements BlockingQueue<Runnable> {
......
}
2 ScheduledThreadPoolExecutor 基本元素
2.1 构造函数
一共有 4
个构造函数,全部都是调用的父类(ThreadPoolExecutor
)的构造函数,任务队列使用的是 DelayedWorkQueue
:
// 第一个构造函数
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue());
}
// 第二个构造函数
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue(), threadFactory);
}
// 第三个构造函数
public ScheduledThreadPoolExecutor(int corePoolSize,
RejectedExecutionHandler handler) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue(), handler);
}
// 第四个构造函数
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue(), threadFactory, handler);
}
2.2 RunnableScheduledFuture 接口
ScheduledThreadPoolExecutor
会将所有实现了 Runnable
接口的任务包装成 RunnableScheduledFuture
接口对象。而 ScheduledFutureTask
就是 RunnableScheduledFuture
接口的实现类:
RunnableScheduledFuture<Void> t = decorateTask(command,
new ScheduledFutureTask<Void>(command, null,
triggerTime(delay, unit),
sequencer.getAndIncrement()));
ScheduledFutureTask
的源码如下:
private class ScheduledFutureTask<V>
extends FutureTask<V> implements RunnableScheduledFuture<V> {
// 任务序号,自增ID
private final long sequenceNumber;
// 首次执行的时间点(单位:纳秒)
private volatile long time;
/**
* 任务类型标识
*
* 0: 非周期任务
* >0: fixed-rate 任务
* <0: fixed-delay 任务
*/
private final long period;
// 重新排队的实际任务
RunnableScheduledFuture<V> outerTask = this;
/**
* 在延时队列中的索引
*/
int heapIndex;
/**
* 构造函数
*/
ScheduledFutureTask(Runnable r, V result, long</