源码:java.util.concurrent.ScheduledThreadPoolExecutor.ScheduledFutureTask<V> 源码解析

1. TODO


2. 脑图

  1. Xmind

  2. Edraw

  3. Hexo 地址
    👉 http://blog.wangjia.ink/2025/11/15/源码:java.util.concurrent.ScheduledThreadPoolExecutor.ScheduledFutureTask<V>源码解析/


3. 基础部分

3.1. ScheduledThreadPoolExecutor.ScheduledFutureTask 概述

ScheduledThreadPoolExecutor.ScheduledFutureTask 是一个具体类,是 java.util.concurrent.ScheduledThreadPoolExecutor 的普通内部类,继承了 java.util.concurrent.FutureTask<V>java.util.concurrent.RunnableScheduledFuture<V>

[!NOTE] 注意事项

  1. 详见源码:FutureTask<V>
    1. obsidian 内部链接:
      1. 源码:java.util.concurrent.FutureTask<V>源码解析
    2. Hexo 链接:
      1. http://blog.wangjia.ink/2025/11/03/源码:java.util.concurrent.FutureTask<V>源码解析/
  2. 详见源码:RunnableScheduledFuture<V>
    1. obsidian 内部链接:
      1. 源码:java.util.concurrent.RunnableScheduledFuture<V>源码解析
    2. Hexo 链接:
      1. http://blog.wangjia.ink/2025/05/05/源码:java.util.concurrent.RunnableScheduledFuture<V>源码解析/

4. 核心属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 表示任务执行点
//
// 哪些需要排序的 Java 数据类型就是以任务执行点进行排序的
private volatile long time;

// 表示任务序号
//
// 如果多个 FutureTask 的任务执行点相同,任务序号小的任务会排在前面
private final long sequenceNumber;

// 表示任务是否是周期性任务,以及如何进行周期性
//
// 可选参数包括:
// 1. 0
// 1. “一次性” 任务
// 2. n(n > 0)
// 1. 以 period 的固定速率,周期性执行任务
// 2. n(n < 0)
// 1. 以 period 的固定延迟,周期性执行任务
private final long period;

// 表示任务对应的二叉堆索引
//
// 堆索引是为了实现快速 Future#cancel 操作的重大优化
//
// 因为 DelayQueue 使用了 PriorityQueue,而 PriorityQueue 底层基于二叉堆,而二叉堆底层又基于数组
//
// 如果没有 heapIndex 并调用 Future#cancel,就需要遍历数组去找到这个任务,然后再进行删除
//
// 如果拥有 heapIndex,当任务在 DelayQueue 变化位置时,会自动更新这个 heapIndex,那么 heapIndex 是直指这个任务的。所以调用 Future#cancel 的时候,就可以直接根据 heapIndex 找到这个任务,然后再进行删除
int heapIndex;

5. 构造方法

5.1. ScheduledFutureTask(Callable<V> callable, long triggerTime, long sequenceNumber)

1
2
3
4
5
6
7
ScheduledFutureTask(Callable<V> callable, long triggerTime,
long sequenceNumber) {
super(callable);
this.time = triggerTime;
this.period = 0;
this.sequenceNumber = sequenceNumber;
}

5.2. ScheduledFutureTask(Runnable r, V result, long triggerTime, long sequenceNumber)

1
2
3
4
5
6
7
ScheduledFutureTask(Runnable r, V result, long triggerTime,
long sequenceNumber) {
super(r, result);
this.time = triggerTime;
this.period = 0;
this.sequenceNumber = sequenceNumber;
}

5.3. ScheduledFutureTask(Runnable r, V result, long triggerTime, long period, long sequenceNumber)

1
2
3
4
5
6
7
ScheduledFutureTask(Runnable r, V result, long triggerTime,
long period, long sequenceNumber) {
super(r, result);
this.time = triggerTime;
this.period = period;
this.sequenceNumber = sequenceNumber;
}

6. 实例方法

6.1. 实例具体方法

6.1.1. 具体方法(普通)

6.1.1.1. void setNextRunTime()
1
2
3
4
5
6
7
private void setNextRunTime() {
long p = period;
if (p > 0)
time += p;
else
time = triggerTime(-p);
}

6.1.2. 具体方法(实现)

6.1.2.1. Comparable<T> 中接口方法的实现
6.1.2.1.1. int compareTo(Delayed other)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public int compareTo(Delayed other) {
if (other == this) // compare zero if same object
return 0;
if (other instanceof ScheduledFutureTask) {
ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
long diff = time - x.time;
if (diff < 0)
return -1;
else if (diff > 0)
return 1;
else if (sequenceNumber < x.sequenceNumber)
return -1;
else
return 1;
}
long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS);
return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}

6.1.2.2. Runnable 中接口方法的实现
6.1.2.2.1. void run()
1
2
3
4
5
6
7
8
9
10
public void run() {
if (!canRunInCurrentRunState(this))
cancel(false);
else if (!isPeriodic())
super.run();
else if (super.runAndReset()) {
setNextRunTime();
reExecutePeriodic(outerTask);
}
}

6.1.2.3. Delayed 中接口方法的实现
6.1.2.3.1. long getDelay(TimeUnit unit)
1
2
3
public long getDelay(TimeUnit unit) {
return unit.convert(time - System.nanoTime(), NANOSECONDS);
}

6.1.2.4. Future<V> 中接口方法的实现
6.1.2.4.1. boolean cancel(boolean mayInterruptIfRunning)
1
2
3
4
5
6
7
8
9
public boolean cancel(boolean mayInterruptIfRunning) {
// The racy read of heapIndex below is benign:
// if heapIndex < 0, then OOTA guarantees that we have surely
// been removed; else we recheck under lock in remove()
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled && removeOnCancel && heapIndex >= 0)
remove(this);
return cancelled;
}

6.1.2.5. RunnableScheduledFuture<V> 中接口方法的实现
6.1.2.5.1. boolean isPeriodic()
1
2
3
public boolean isPeriodic() {
return period != 0;
}


源码:java.util.concurrent.ScheduledThreadPoolExecutor.ScheduledFutureTask<V> 源码解析
https://wangjia5289.github.io/2025/11/15/源码:java.util.concurrent.ScheduledThreadPoolExecutor.ScheduledFutureTask<V>源码解析/
Author
咸阳猴🐒
Posted on
November 15, 2025
Licensed under