转载自https://github.com/Snailclimb/JavaGuide(添加小部分笔记)感谢作者!
为什么需要定时任务?#
我们来看一下几个非常常见的业务场景:
- 某系统凌晨要进行数据备份。
- 某电商平台,用户下单半个小时未支付的情况下需要自动取消订单。
- 某媒体聚合平台,每 10 分钟动态抓取某某网站的数据为自己所用。
- 某博客平台,支持定时发送文章。
- 某基金平台,每晚定时计算用户当日收益情况并推送给用户最新的数据。
- ……
这些场景往往都要求我们在某个特定的时间去做某个事情。
单机定时任务技术选型#
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 )。

















