Timer和TimerTask是Java轻量级单线程定时方案,适合低频非关键任务;但存在异常终止、阻塞卡死、线程泄漏等严重缺陷,现推荐使用ScheduledExecutorService替代。
Timer 和 TimerTask 的基本用法
Java 的 Timer 配合 TimerTask 是最轻量的原生定时方案,适合单线程、低频、非关键任务。它不是为高并发或高精度设计的,底层靠一个单独的后台线程驱动所有任务。
典型写法是继承 TimerTask 实现 run() 方法,再用 Timer.schedule() 或 Timer.scheduleAtFixedRate() 注册执行逻辑:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
System.out.println("执行一次");
}
}, 1000); // 延迟 1 秒后执行
注意:一旦 TimerTask.run() 抛出未捕获异常,该 Timer 实例会彻底停止,后续所有任务都不会再触发 —— 这是最常被忽略的崩溃点。
schedule() 和 scheduleAtFixedRate() 的区别
两个调度方法表面相似,但对“延迟执行”和“任务耗时超预期”的处理完全不同:
立即学习“Java免费学习笔记(深入)”;
-
schedule():以“上一次实际执行完成时间”为基准计算下一次触发点。如果某次任务耗时 800ms,而间隔设为 500ms,那下次会等当前执行完再延后 500ms 才启动 —— 会自动退避,不会堆积 -
scheduleAtFixedRate():以“首次计划开始时间”为基准,严格按周期推进。同样耗时超限的情况下,它会立即连续触发(甚至并发执行),试图追平节奏 —— 可能导致任务重叠或资源争抢
例如:设定每 500ms 执行一次,某次运行卡住 2 秒,则: