Timer的工作原理
Timer本质上是一个后台线程,它会调度执行所有加入到Timer中的task。所有加入到Timer中的task可以只被调度执行一次,也可以每隔一定的时间间隔重复的被Timer调度执行。
Timer主要由以下两部分组成
TaskQueue :每个Timer中包含一个TaskQueue对象,这个队列存储了所有将被调度的task, 该队列是一个根据task下一次运行时间排序形成的最小优先队列,该最小优先队列的是一个二叉堆,所以可以在log(n)的时间内完成增加task,删除task等操作,并且可以在常数时间内获得下次运行时间最小的task对象。该队列初始大小为128,当队列中的task总数超过队列大小时,队列大小就会翻倍。
TimerThread :TimerThread是一个继承自Thread的类,该类的run方法执行所有task的调度工作。
1、task队列的建立
我们每次使用Timer的时候肯定会使用scheule或者scheuleAtFixedRate方法将一个TimerTask对象传递给Timer,其实这两个方法的主要实现都是一样的,(下一节将探讨两者的不同及其实现),他们都会调用一个private方法sched (代码如下),该方法会设置每个task的属性, 包括nextExecutionTime、调度间隔period,和state,然后将这个task加入到 task 队列 queue 中。我们可能对于最后的notify有点困惑,这个在后面会有说明。
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