一、任务精确性
通过前两节的分析,大概知道了Timer的运行原理,下面说说使用Timer需要注意的一些事项。下面是Timer简单原理图
从上图可以看到,真正运行闹钟的是一个单线程。也就是说队列中的闹钟,只能依次进行串行化的操作,闹钟的定时执行得不到保证。
比如下面的例子(本节所有代码只列出关键部分,下同)。
public class ScheduleDemo {
public static void main(String[] args) throws Exception {
Timer timer = new Timer();
timer.schedule(new AlarmTask("闹钟"),1000,2000);
}
static class AlarmTask extends TimerTask {
public void run() {
log.info(new Date() +" 嘀。。。");
Thread.sleep(10_000); //模拟闹钟执行时间
}
}
}
从下面的运行结果可以看到,预期2秒以后运行的闹钟,推迟到了10秒以后。
Fri Nov 16 14:49:39 CST 2018 嘀。。。
Fri Nov 16 14:49:49 CST 2018 嘀。。。
下面是闹钟运行的时序图
解决方法
针对上面的情况,用户可在AlarmTask.run()里面再开一个异步线程,让TimerThread及时返回,执行队列中后续的闹钟。
public class ScheduleDemo {
public static void main(String[] args) throws Exception {
Timer timer = new Timer();
timer.schedule(new AlarmTask("闹钟"),1000,2000);
}
static class AlarmTask extends TimerTask{
static ExecutorService threadPool = Executors.