Timer定时器
Timer类实现的主要组成部分为下面这两个成员变量:
1 /** 2 * The timer task queue. This data structure is shared with the timer 3 * thread. The timer produces tasks, via its various schedule calls, 4 * and the timer thread consumes, executing timer tasks as appropriate, 5 * and removing them from the queue when they're obsolete. 6 */ 7 private final TaskQueue queue = new TaskQueue(); 8 9 /** 10 * The timer thread. 11 */ 12 private final TimerThread thread = new TimerThread(queue);
java.util.TimerThread继承Thread类,内部维护一个TaskQueue变量,然后run方法中无限循环从TaskQueue中取出第一个节点任务执行
当开始队列为空的时候,调用queue.wait();进入等待队列,当第一个节点任务加入后调用queue.notify();唤醒等待线程后,进入无限循环中。
TaskQueue中维护一个private TimerTask[] queue = new TimerTask[128];数组,需要扩容时,则扩大2倍,
1 if (size + 1 == queue.length) 2 queue = Arrays.copyOf(queue, 2*queue.length);
TaskQueue其实是一个平衡二叉堆(小根堆),根据下次最先执行的时间来排序,所以最先执行的任务总是在堆的根上。在每次添加节点和删除节点时
通过方法fixUp和fixDown来调整堆:
1 /** 2 * Establishes the heap invariant (described above) assuming the heap 3 * satisfies the invariant except possibly for the leaf-node indexed by k 4 * (which may have a nextExecutionTime less than its parent's). 5 * 6 * This method functions by "promoting" queue[k] up the hierarchy 7 * (by swapping it with its parent) repeatedly until queue[k]'s 8 * nextExecutionTime is greater than or equal to that of its parent. 9 */ 10 private void fixUp(int k) { 11 while (k > 1) { 12 int j = k >> 1; 13 if (queue[j].nextExecutionTime <= queue[k].nextExecutionTime) 14 break; 15 TimerTask tmp = queue[j]; queue[j] = queue[k]; queue[k] = tmp; 16 k = j; 17 } 18 } 19 20 /** 21 * Establishes the heap invariant (described above) in the subtree 22 * rooted at k, which is assumed to satisfy the heap invariant except 23 * possibly for node k itself (which may have a nextExecutionTime greater 24 * than its children's). 25 * 26 * This method functions by "demoting" queue[k] down the hierarchy 27 * (by swapping it with its smaller child) repeatedly until queue[k]'s 28 * nextExecutionTime is less than or equal to those of its children. 29 */ 30 private void fixDown(int k) { 31 int j; 32 while ((j = k << 1) <= size && j > 0) { 33 if (j < size && 34 queue[j].nextExecutionTime > queue[j+1].nextExecutionTime) 35 j++; // j indexes smallest kid 36 if (queue[k].nextExecutionTime <= queue[j].nextExecutionTime) 37 break; 38 TimerTask tmp = queue[j]; queue[j] = queue[k]; queue[k] = tmp; 39 k = j; 40 } 41 }
新增节点时调用fixUp方法,不断与父节点比较大小,如果小于父节点则交换位置继续比较
删除节点时调用fixDown方法,不断与子节点比较大小,如果比最小的子节点大,则交换位置,接着继续比较
其等待到任务执行时间主要是通过wait(long timeout)方法等待超时来实现的:
1 queue.wait(executionTime - currentTime);