什么是 Java 的 Timer?
什么是 Java 的 Timer?
回答重点
Java 的 Timer 是一个用于调度任务的工具类,用于在未来某个时刻执行任务或周期性地执行任务。Timer 类一般与 TimerTask 搭配使用,其中 TimerTask 是一个需要执行的任务。
适用于简单的定时任务,如定时更新、定期发送报告等。
扩展知识
Timer 使用
TimerTask 是 Timer 需要执行的任务,它是一个实现了 Runnable 接口的抽象类,必须通过继承并实现其 run() 方法。
基本使用:
- 使用
Timer.schedule(TimerTask task, long delay)在指定的延迟之后执行任务。 - 使用
Timer.scheduleAtFixedRate(TimerTask task, long delay, long period)周期性地执行任务。
示例代码:
1 | Timer timer = new Timer(); |
Timer 原理分析
Timer 可以实现延时任务,也可以实现周期性任务,它的核心就是一个优先队列和封装的执行任务的线程。
实现原理是:维持一个小顶堆,即最快需要执行的任务排在优先队列的第一个,根据堆的特性我们知道插入和删除的时间复杂度都是 O(logn)。
然后有个 TimerThread 线程不断地拿排着的第一个任务的执行时间和当前时间做对比。
如果时间到了先看看这个任务是不是周期性执行的任务,如果是则修改当前任务时间为下次执行的时间,如果不是周期性任务则将任务从优先队列中移除。最后执行任务。如果时间还未到则调用 wait() 等待。
可以看出 Timer 实际就是根据任务的执行时间维护了一个优先队列,并且起了一个线程不断地拉取任务执行。
Timer 有什么弊端呢?
首先优先队列的插入和删除的时间复杂度是O(logn),当数据量大的时候,频繁的入堆出堆性能有待考虑。
并且是单线程执行,那么如果一个任务执行的时间过久则会影响下一个任务的执行时间(当然你任务的run要是异步执行也行)。
并且从它对异常没有做什么处理,所以一个任务出错的时候会导致之后的任务都无法执行。
ScheduledExecutorService
ScheduledExecutorService 是 Java 5 引入的替代方案,功能更强大。它支持多线程并行调度任务,能更好地处理任务调度的复杂场景。
因为使用线程池进行任务调度,所以不会因某个任务的异常终止而导致其他任务停止。并且它提供了更灵活的 API,可以更精细地控制任务的执行周期和策略。
推荐使用 ScheduledExecutorService 替代 Timer。