Timer实现
使用:
入口1:private Timer mTimer = new Timer();
入口2:mTimer.schedule(new TimerTask() {// schedule(TimerTask task, long delay, long period)
@Override
public void run() {
//System.out.println("timer running...");
updateWidgetTime();
}
1000, 1000};
源码分析:
入口1:
// 1.
public Timer() {
impl = new TimerImpl("java.util.Timer", false);
}
// 2.启动线程查询是否有任务
TimerImpl(String name, boolean isDaemon) {// TimerImpl继承自Thread
this.setName(name);
this.setDaemon(isDaemon);
this.start();// 开启线程
}
入口2:
// 3.插入一个任务队列
public void schedule(TimerTask task, long delay, long period) {
scheduleImpl(task, delay, period, false);// schedule:时刻表
}
private void scheduleImpl(TimerTask task, long delay, long period,
boolean fixed) {
long when = delay + System.currentTimeMillis();// 下一次schedule的时间
task.when = when;
task.period = period;
task.fixedRate = fixed;
// insert the newTask into queue
impl.insertTask(task);// 将TimerTask插入到TimerTree中
/*
private void insertTask(TimerTask newTask) {
// callers are synchronized
tasks.insert(new TimerNode(newTask));
this.notify();
}
}
*/
}
// 4.线程执行,不断查询任务并执行
TimerImpl.run // 线程中执行各个任务
@Override
public void run() {
while (true) {
TimerTask task;
// 5.查找是否有任务需要执行
// need to check cancelled inside the synchronized block
if (cancelled) {
return;
}
if (tasks.isEmpty()) {
if (finished) {
return;
}
// no tasks scheduled -- sleep until any task appear
this.wait();// 如果任务队列中没有任务,则休眠
continue;// wait方法经常和while+continue何用
}
// 6.计算距任务执行还需要的时间,并且sleep消耗掉剩余时间
long currentTime = System.currentTimeMillis();
TimerNode taskNode = tasks.minimum(); // 取出任务队列中离任务执行剩余时间最少的任务
task = taskNode.task;
long timeToSleep;
if (task.cancelled) {
tasks.delete(taskNode);
continue;
}
// check the time to sleep for the first task scheduled
timeToSleep = task.when - currentTime;
if (timeToSleep > 0) {
// sleep!
this.wait(timeToSleep);// 把任务执行还剩余时间消耗掉
continue; // continue用法同上
}
// 7.执行到点的任务,并删除该任务,如果该任务是repeat,则重新设置定点时间,并把任务重新添加到队列
// no sleep is necessary before launching the task
if (task.cancelled) {
tasks.delete(taskNode);
continue;
}
// set time to schedule
task.setScheduledTime(task.when); // 内部实现:scheduledTime = time;(将when赋值给schedule)
// remove task from queue
tasks.delete(taskNode); // 将未来要执行的任务删除队列。 删除即将执行的任务节点
// 循环定时器,而非只定时一次
// set when the next task should be launched
if (task.period >= 0) {
// this is a repeating task,
// task is scheduled at fixed delay
task.when = System.currentTimeMillis()
+ task.period;
// insert this task into queue
insertTask(task); // 将当前任务重新插入到队列
} else {
task.when = 0;
}
task.run();// 真正的业务执行代码
}
}
小结:
1.Timer中对象的关系:
-Timer
-TimerImpl 定时器的控制对象,内部维护TimerTree。本质是线程类
——TimerTree 定时器队列,内部维护TimerNode链表
-TimerNode 定时器节点,内部维护一个定时任务
-TimerTask 定时任务,内部是具体定是任务执行代码(内部实现Runnable接口)
2.大概执行过程:如步骤1-7
创建定时器(本质是线程类),并执行线程方法,线程方法查询当前任务队列中是否有任务队列,如果有任务直接执行任务,
并将任务移除队列,重新添加任务到任务队列中。
补充:各个类核心成员数据
private static final class TimerImpl extends Thread {
/**
* True if the method cancel() of the Timer was called or the !!!stop()
* method was invoked
*/
private boolean cancelled;
/**
* True if the Timer has become garbage
*/
private boolean finished;
/**
* Vector consists of scheduled events, sorted according to
* {@code when} field of TaskScheduled object.
*/
private TimerTree tasks = new TimerTree();// TimerTree维护着TimerTree
}
private static final class TimerTree {
int deletedCancelledNumber;
TimerNode root;
}
private static final class TimerNode {
TimerNode parent, left, right;
TimerTask task;
public TimerNode(TimerTask value) {
this.task = value;
}
public void deleteIfCancelled(TimerTree tasks) {// 删除TimeTree上的TiemNode节点
/*
* All changes in the tree structure during deleting this node
* affect only the structure of the subtree having this node as
* its root
*/
if (left != null) {
left.deleteIfCancelled(tasks);
}
if (right != null) {
right.deleteIfCancelled(tasks);
}
if (task.cancelled) {
tasks.delete(this);
tasks.deletedCancelledNumber++;
}
}
}
}
public abstract class TimerTask implements Runnable {
/* Lock object for synchronization. It's also used by Timer class. */
final Object lock = new Object();
/* If timer was cancelled */
boolean cancelled;
/* Slots used by Timer */
long when;
long period;
boolean fixedRate;
/*
* The time when task will be executed, or the time when task was launched
* if this is task in progress.
*/
private long scheduledTime;
}