Timer的核心代码:
private void mainLoop() {
while (true) {
try {
TimerTask task;
boolean taskFired = false;
synchronized (queue) {
while (queue.isEmpty() && newTasksMayBeScheduled) {
queue.wait();
}
if (queue.isEmpty())
break; // 直接挑出mainLoop了.
long currentTime, executionTime;
task = queue.getMin(); // 获取这个任务队列第一个任务
synchronized (task.lock) {
if (task.state == TimerTask.CANCELLED) {
queue.removeMin();
continue;
}
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)
queue.wait(executionTime - currentTime);
}
if (taskFired) // Task fired; run it, holding no locks
task.run();
} catch (InterruptedException e) {
}
}// while(true)
}
但是Timer和TimerTask存在一些缺陷:
1:Timer只创建了一个线程。当你的任务执行的时间超过设置的延时时间将会产生一些问题。
2:Timer创建的线程没有处理异常,因此一旦抛出非受检异常,该线程会立即终止。
JDK 5.0以后推荐使用ScheduledThreadPoolExecutor。该类属于Executor Framework,它除了能处理异常外,还可以创建多个线程解决上面的问题。
使用:任务继承 Runnable 接口来执行线程