为什么需要定时任务?
我们来看一下几个非常常见的业务场景:
- 某系统凌晨 1 点要进行数据备份。
- 某电商平台,用户下单半个小时未支付的情况下需要自动取消订单。
- 某媒体聚合平台,每 10 分钟动态抓取某某网站的数据为自己所用。
- 某博客平台,支持定时发送文章。
- 某基金平台,每晚定时计算用户当日收益情况并推送给用户最新的数据。
- ……
这些场景往往都要求我们在某个特定的时间去做某个事情,也就是定时或者延时去做某个事情。
- 定时任务:在指定时间点执行特定的任务,例如每天早上 8 点,每周一下午 3 点等。定时任务可以用来做一些周期性的工作,如数据备份,日志清理,报表生成等。
- 延时任务:一定的延迟时间后执行特定的任务,例如 10 分钟后,3 小时后等。延时任务可以用来做一些异步的工作,如订单取消,推送通知,红包撤回等。
尽管二者的适用场景有所区别,但它们的核心思想都是将任务的执行时间安排在未来的某个点上,以达到预期的调度效果。
单机定时任务
Timer
java.util.Timer是 JDK 1.3 开始就已经支持的一种定时任务的实现方式。
Timer 内部使用一个叫做 TaskQueue 的类存放定时任务,它是一个基于最小堆实现的优先级队列。TaskQueue 会按照任务距离下一次执行时间的大小将任务排序,保证在堆顶的任务最先执行。这样在需要执行任务时,每次只需要取出堆顶的任务运行即可!
Timer 使用起来比较简单,通过下面的方式我们就能创建一个 1s 之后执行的定时任务。
// 示例代码:
TimerTask task = new TimerTask() {
public void run() {
System.out.println("当前时间: " + new Date() + "n" +
"线程名称: " + Thread.currentThread().getName());
}
};
System.out.println("当前时间: " + new Date() + "n" +
"线程名称: " + Thread.currentThread().getName());
Timer timer = new Timer("Timer");
long delay = 1000L;
timer.schedule(task, delay);
//输出:
当前时间: Fri May 28 15:18:47 CST 2021n线程名称: main
当前时间: Fri May 28 15:18:48 CST 2021n线程名称: Timer
不过其缺陷较多,比如一个 Timer 一个线程,这就导致 Timer 的任务的执行只能串行执行,一个任务执行时间过长的话会影响其他任务(性能非常差),再比如发生异常时任务直接停止(Timer 只捕获了 InterruptedException )。
Timer 类上的有一段注释是这样写的:
* This class does not offer real-time guarantees: it schedules
* tasks using the <tt>Object.wait(long)</tt> method.
*Java 5.0 introduced the {@code java.util.concurrent} package and
* one of the concurrency utilities therein is the {@link
* java.util.concurrent.ScheduledThreadPoolExecutor
* ScheduledThreadPoolExecutor} which is a thread pool for repeatedly
* executing tasks at a given rate or delay. It is effectively a more
* versatile replacement for the {@code Timer}/{@code TimerTask}
* combination, as it allows multiple service threads, accepts various
* time units, and doesn't require subclassing {@code TimerTask} (just
* implement {@code Runnable}). Configuring {@code
* ScheduledThreadPoolExecutor} with one thread makes it equivalent to
* {@code Timer}.
大概的意思就是:ScheduledThreadPoolExecutor 支持多线程执行定时任务并且功能更强大,是 Timer 的替代品。

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



