1.首先看Timer源码:
public class Timer { private final TaskQueue queue = new TaskQueue(); private final TimerThread thread = new TimerThread(queue); public Timer() { this("Timer-" + serialNumber()); } public Timer(String name) { thread.setName(name); thread.start(); } private void sched(TimerTask task, long time, long period) { if (time < 0) throw new IllegalArgumentException("Illegal execution time."); // Constrain value of period sufficiently to prevent numeric // overflow while still being effectively infinitely large. if (Math.abs(period) > (Long.MAX_VALUE >> 1)) period >>= 1; synchronized(queue) { if (!thread.newTasksMayBeScheduled) throw new IllegalStateException("Timer already cancelled."); synchronized(task.lock) { if (task.state != TimerTask.VIRGIN) throw new IllegalStateException( "Task already scheduled or cancelled"); task.nextExecutionTime = time; task.period = period; task.state = TimerTask.SCHEDULED; } queue.add(task); if (queue.getMin() == task) queue.notify(); } } }
这里贴出来的是主要的代码部分,Timer里有两个成员变量
private final TaskQueue queue = new TaskQueue();
private final TimerThread thread = new TimerThread(queue);
2.TaskQueue的源码如下:
class TaskQueue { private TimerTask[] queue = new TimerTask[128]; private int size = 0; int size() { return size; } void add(TimerTask task) { // Grow backing store if necessary if (size + 1 == queue.length) queue = Arrays.copyOf(queue, 2*queue.length); queue[++size] = task; fixUp(size); } TimerTask getMin() { return queue[1]; } TimerTask get(int i) { return queue[i]; } void removeMin() { queue[1] = queue[size]; queue[size--] = null; // Drop extra reference to prevent memory leak fixDown(1); } void quickRemove(int i) { assert i <= size; queue[i] = queue[size]; queue[size--] = null; // Drop extra ref to prevent memory leak } void rescheduleMin(long newTime) { queue[1].nextExecutionTime = newTime; fixDown(1); } boolean isEmpty() { return size==0; } void clear() { // Null out task references to prevent memory leak for (int i=1; i<=size; i++) queue[i] = null; size = 0; } private void fixUp(int k) { while (k > 1) { int j = k >> 1; if (queue[j].nextExecutionTime <= queue[k].nextExecutionTime) break; TimerTask tmp = queue[j]; queue[j] = queue[k]; queue[k] = tmp; k = j; } } private void fixDown(int k) { int j; while ((j = k << 1) <= size && j > 0) { if (j < size && queue[j].nextExecutionTime > queue[j+1].nextExecutionTime) j++; // j indexes smallest kid if (queue[k].nextExecutionTime <= queue[j].nextExecutionTime) break; TimerTask tmp = queue[j]; queue[j] = queue[k]; queue[k] = tmp; k = j; } } void heapify() { for (int i = size/2; i >= 1; i--) fixDown(i); } }
TaskQueue有个变量为TimerTask的数组,它存放了所有添加进来的任务。而且将即将要执行的任务放到index为1的位置,而且每次条用add方法添加任务的时候都会对数组的排列顺序进行一次调整。而TimerTask是一个实现了Runnable接口的类。
3.TimerThread的源码:
class TimerThread extends Thread { boolean newTasksMayBeScheduled = true; private TaskQueue queue; TimerThread(TaskQueue queue) { this.queue = queue; } public void run() { try { mainLoop(); } finally { // Someone killed this Thread, behave as if Timer cancelled synchronized(queue) { newTasksMayBeScheduled = false; queue.clear(); // Eliminate obsolete references } } } 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) { } } } }
这是个继承了Thread的线程类。主要的方法是mainLoop,循环检查是否有任务到了执行的时间,如果有就调用task的run方法进行执行。
4.所以总体的流程就是,创建一个Timer对象,然后把需要执行的任务封装到一个TimeTask对象里,添加到Timer的任务列表里(TaskQueue,一个TimeTask数组)。因为Timer里有一个成员变量TimerThreed,一个线程类,Timer在创建的时候就会使此线程运行,TimerThreed里一个死循环的代码段,此代码段不断的检查任务数组中是否有需要执行的任务,如果有就执行任务的run方法来完成任务的调用。
5.因为此实现是单线程负责任务的调度,所有会出现任务阻塞,延迟,甚至一个任务异常会影响全部任务的执行。