在 JDK 中,内置了两个类,可以实现定时任务的功能:
- java.util.Timer :可以通过创建 java.util.TimerTask 调度任务,在同一个线程中串行执行,相互影响。也就是说,对于同一个 Timer 里的多个 TimerTask 任务,如果一个 TimerTask 任务在执行中,其它 TimerTask 即使到达执行的时间,也只能排队等待。因为 Timer 是串行的,同时存在 坑坑 ,所以后来 JDK 又推出了 ScheduledExecutorService ,Timer 也基本不再使用。
- java.util.concurrent.ScheduledExecutorService :在 JDK 1.5 新增,基于线程池设计的定时任务类,每个调度任务都会被分配到线程池中并发执行,互不影响。这样,ScheduledExecutorService 就解决了 Timer 串行的问题。
但是它们仅支持按照指定频率,不直接支持指定时间的定时调度,需要结合Calendar自行计算,才能实现复杂时间的调度。
它们是进程级别,而我们为了实现定时任务的高可用,需要部署多个进程。此时需要多考虑,多个进程下,同一个任务在相同时刻,不能重复执行
项目可能存在定时任务较多,需要统一的管理,此时不得不进行二次封装
所以我们可以用调度任务中间件
在 Spring 体系中,内置了两种定时任务的解决方案:
- 第一种,Spring Framework 的 Spring Task 模块,提供了轻量级的定时任务的实现。
- 第二种,Spring Boot 2.0 版本,整合了 Quartz 作业调度框架,提供了功能强大的定时任务的实现。
注:Spring Framework 已经内置了 Quartz 的整合。Spring Boot 1.X 版本未提供 Quartz 的自动化配置,而 2.X 版本提供了支持。
Spring Task
- 创建配置类,启动定时任务
// ScheduleConfiguration.java
@Configuration
@EnableScheduling
public class ScheduleConfiguration {
}
在类上,通过添加 @EnableScheduling 注解,启动 Spring Task 的定时任务调度的功能。
- 创建任务类
@Component
public class TaskDemo {
private Logger logger = LoggerFactory.getLogger(getClass());
private final AtomicInteger counts = new AtomicInteger();
@Scheduled(fixedRate = 2000)
public void execute() {
logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet());
}
}
其中的 #execute() 方法用于实现任务要执行的内容,这里是打印一下日志。
同时,在该方法上,添加 @Scheduled 注解,设置每 2 秒执行该方法。
@Configuration
@EnableScheduling//开启定时任务
@EnableAsync//开启多线程
pubic class config{
@Scheduled(cron="0 0 23 * * ?")//每天23点执行
@Async//异步
public void

最低0.47元/天 解锁文章
3179

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



