Timer

Timer

变量:

  • TaskQueue queue 在TashQueue中 private TimerTask[] queue = new TimerTask[128];
  • TimerThread thread class TimerThread extends Thread

缺点:只有一个thread来执行所有的任务,如果有个任务抛出异常,那么所有的任务就会停止,

如果存在多个任务,切任务的时间很长,导致执行结果于预期不符

构造函数
1
2
3
4
5
public Timer(String name, boolean isDaemon) {
thread.setName(name);
thread.setDaemon(isDaemon);
thread.start();
}

TimerThread的运行:每次执行之后之后都会对数组中排序,最小的放在最上面,有可能有多个任务,任务的执行时间长的话,就推到下个周期。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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为空,直接跳出。

// Queue nonempty; look at first evt and do the right thing
long currentTime, executionTime;
//每次拿到的是queue[1],也是最小的
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;
//超过了时间,踢掉任务。
//period:0非重复任务
//正值:在执行完一个任务的基础上,等+period个时间。
//负值:固定延迟执行:
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) {
}
}
}

schedule()方法

设置定时任务的时间,time:指定时间后,period时间间隔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    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();
}
}
//队列中时间的调整
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;
}
}