1. 整体图解

整体结构图解
2. 包含任务执行逻辑的 TimerTask 抽象类
- 任务抽象类
TimerTask的生命周期表示如下:

TimerTask的生命周期
- 任务抽象类
TimerTask的属性详细解释如下:

TimerTask类的属性解析
- 任务抽象类
TimerTask的实例方法:

TimerTask类的实例方法
3. 任务队列 TaskQueue 类
TaskQueue内部采用最小堆来实现优先队列, 其各种操作的复杂度不超过O(logn)
-
TaskQueue类的属性

TaskQueue类的属性
-
TaskQueue类的实例方法
TaskQueue类的实例方法
TaskQueue类的实例方法
TaskQueue类的实例方法
辅助方法来维持最小堆的性质
4. 执行任务的线程类 TimerThread
执行任务的线程类
TimerThread继承Thread类, 用来执行任务队列中的任务, 因此,Timer类调度的所有任务都是在单线程中按执行时间先后顺序执行的
-
TimerThread类的属性
TimerThread类的属性 -
TimerThread类的实例方法
run方法
mainloop 方法详细解释如下:
private void mainLoop() {
while (true) {
try {
TimerTask task;
boolean taskFired;
synchronized (queue) {
// 任务队列为空, 让当前执行线程放弃queue锁
while (queue.isEmpty() && newTasksMayBeScheduled) {
queue.wait();
}
// 执行期间发现任务队列为空, 即没有任务需要执行, 因此跳出循环
if (queue.isEmpty()) {
break;
}
long currentTime, executionTime;
task = queue.getMin();
synchronized (task.lock) {
if (task.state == TimerTask.TimerTaskStatus.CANCELLED) {
queue.removeMin();
continue; // 开始下一次循环去执行下一个任务
}
currentTime = System.currentTimeMillis();
executionTime = task.nextExecutionTime;
if (taskFired = (executionTime <= currentTime)) { // 任务的开始时间早于当前时间, 则立即执行
if (task.period == 0) { // 非周期型任务
queue.removeMin();
task.state = TimerTask.TimerTaskStatus.EXECUTED;
} else { // 周期型任务
// schedule 与 scheduleAtFixedRate 的区别体现在这里
// 当执行时间早于当前时间时, schedule系列方法执行时没有追赶性, scheduleAtFixedRate系列方法执行时具有追赶性
queue.rescheduleMin(task.period < 0 ? currentTime - task.period : executionTime + task.period);
}
}
}
if (!taskFired) { // 还未到时间执行任务
queue.wait(executionTime - currentTime);
}
}
if (taskFired) { // 可以执行任务(注意: 没有锁)
task.run();
}
} catch (InterruptedException e) {
}
}
}
5. Timer 类解析
-
Timer类的属性

Timer类的属性
-
Timer类的构造方法

Timer类的构造方法
-
Timer类的cancel()方法

cancel方法
-
schedule系列方法

schedule系列方法
-
scheduleAtFixedRate系列方法

scheduleAtFixedRate系列方法
schedule 和 scheduleAtFixedRate 方法的具体执行逻辑放在 sched 方法上:
private void sched(TimerTask task, long time, long period) {
// 验证参数是否正确
if (time < 0) {
throw new IllegalArgumentException("Illegal execution time.");
}
if (Math.abs(period) > (Long.MAX_VALUE >> 1)) {
period >>= 1;
}
// 将任务task的属性设置好并存放在任务队列queue上
synchronized (queue) {
if (!thread.newTasksMayBeScheduled) {
throw new IllegalArgumentException("Timer already cancelled.");
}
synchronized (task.lock) {
if (task.state != TimerTask.TimerTaskStatus.VIRGIN) {
throw new IllegalArgumentException("Task already scheduled or cancelled!");
}
task.nextExecutionTime = time;
task.period = period;
task.state = TimerTask.TimerTaskStatus.SCHEDULED;
}
queue.add(task);
// 若加入任务前队列为空则要通知执行任务的线程, 使其从WAITING状态切换为RUNNABLE状态
if (queue.getMin() == task) {
queue.notify();
}
}
}
注意:
schedule和scheduleAtFixedRate方法的区别在于当执行时间早于当前时间时,schedule方法不具有追赶性, 而scheduleAtFixedRate方法具有追赶性;






