写在前面:Timer使用一个队列缓存要执行的任务,可以加入多个TimerTask,在一个独立线程中顺序执行任务。
首先看看Timer的成员和内部方法:
schedule(TimerTask task,long delay)
…
首先包含多个schedule的多态方法。
Timer 构造方法的多态
持有一个TimerQueue 的队列,也就是前面所说的用于缓存待执行任务的队列。
持有一个TimerThread的变量,就是前面说的工作线程。
结构,内容都比较简单,下面慢慢来分析。
有一个队列,那么大胆猜测,是可以执行多个TimerTask,有一个线程,那么同时猜测,是在单独线程去执行Timer。
下面看一下,工作线程TimerThread这个类的实现。
Class TimerThread extends Thread {
private TimerQueue queue;
TimerThread(TimerQueue queue){
this.queue= queue;
}
public void run(){
try{
mainLoop();//关键方法。
}finally{
…
}
}
}
下面看一下 mainloop()的实现 。
/**
* The main timer loop. (See class comment.)
*/
private void mainLoop() {
while (true) {
try {
TimerTask task;
boolean taskFired;
synchronized(queue) {
// Wait for queue to become non-empty
while (queue.isEmpty() && newTasksMayBeScheduled)
queue.wait();
if (queue.isEmpty())
break; // Queue is empty and will forever remain; die
// Queue nonempty; look at first evt and do the right thing
long currentTime, executionTime;
task = queue.getMin();
synchronized(task.lock) {
if (task.state == TimerTask.CANCELLED) {
queue.removeMin();
continue; // No action required, poll queue again
}
currentTime = System.currentTimeMillis();
executionTime = task.nextExecutionTime;
if (taskFired = (executionTime<=currentTime)) {
if (task.period == 0) { // Non-repeating, remove
queue.removeMin();
task.state = TimerTask.EXECUTED;
} else { // Repeating task, reschedule
//按照下次执行时间对队列进行重新排序。
queue.rescheduleMin(
task.period<0 ? currentTime - task.period
: executionTime + task.period);
}
}
}
if (!taskFired) // Task hasn't yet fired; wait
//如果时间还没到,那么等待剩余时长。
queue.wait(executionTime - currentTime);
}
if (taskFired) // Task fired; run it, holding no locks
//时间到了或者时间已经过了,那么立刻执行。
task.run();//同步执行,如果这里执行时间过长,就会影响到后续的执行时间。
} catch(InterruptedException e) {
}
}
}