定时工作是每个业务常见的需要,比方每分钟扫描超时领取的订单,每小时清理一次数据库历史数据,每天统计前一天的数据并生成报表等等。常见的解决方案有 XXL-JOB、Spring-Task 等。本篇文章着重于探讨 Java 定时工作技术的倒退历程。
一、Timer
java.util.Timer 是 JDK 原生的工具类,用于创立定时工作。
创立 java.util.TimerTask 工作,在 run 办法中实现业务逻辑。通过 java.util.Timer 进行调度,反对依照固定频率或指定 Date 时刻执行。所有的 TimerTask 是在同一个线程中串行执行,相互影响。也就是说,对于同一个 Timer 里的多个 TimerTask 工作,如果一个 TimerTask 工作在执行中,其它 TimerTask 即便达到执行的工夫,也只能排队期待。如果有异样产生,线程将退出,整个定时工作就失败。
TimerTask timerTask1 = new TimerTask() {
@SneakyThrows
@Override
public void run() {System.out.println("timerTask1 run ...");
Thread.sleep(10000);
System.out.println("timerTask1 finish ...");
}
};
TimerTask timerTask2 = new TimerTask() {
@Override
public void run() {System.out.println(System.currentTimeMillis());
System.out.println("timerTask2 run ...");
}
};
Timer timer = new Timer();
DateTime date = DateUtil.parse("2022-08-04 15:30:00", DatePattern.NORM_DATETIME_PATTERN);
timer.schedule(timerTask1, date);
timer.schedule(timerTask2, 15000);
二、ScheduledExecutorService
ScheduledExecutorService 是 java.util.concurrent 包下基于线程池设计的定时工作解决方案。
每个调度工作都会调配到线程池中的一个线程去执行,解决 Timer 定时器无奈并发执行的问题,反对 fixedRate 和 fixedDelay。
public class ScheduledExecutorServiceTest {
private static final int CORE_SIZE = 5;
public static void main(String[] args) {ScheduledExecutorService executorService = Executors.newScheduledThreadPool(CORE_SIZE);
// 依照固定频率执行,每隔 5 秒跑一次
executorService.scheduleAtFixedRate(() -> System.out.println("hello fixedRate"), 10, 5, TimeUnit.SECONDS);
// 依照固定延时执行,上次执行完后隔 5 秒执行下一次
executorService.scheduleWithFixedDelay(() -> System.out.println("hello fixedDelay"), 10, 5, TimeUnit.SECONDS);
}
}
三、Spring Task
Spring Task 是 SpringBoot 提供的轻量级定时工作工具。
咱们通过注解能够很不便的配置,反对 cron 表达式、fixedRate、fixedDelay。
@Component
@EnableScheduling
public class SpringTaskTest {
/**
* 每分钟的第 30 秒跑一次
*/
@Scheduled(cron = "30 * * * * ?")
public void task1() throws InterruptedException {System.out.println("hello cron");
}
/**
* 每隔 5 秒跑一次
*/
@Scheduled(fixedRate = 5000)
public void task2() throws InterruptedException {System.out.println("hello fixedRate");
}
/**
* 上次跑完隔 3 秒再跑
*/
@Scheduled(fixedDelay = 3000)
public void task3() throws InterruptedException {System.out.println("hello fixedDelay");
}
}
四、Quartz
Quartz 是一套轻量级的任务调度框架,由 Java 编写。
咱们只须要定义了 Job(工作),Trigger(触发器)和 Scheduler(调度器),即可实现一个定时调度能力。反对基于数据库的集群模式,实质上还是抢 DB 锁。
五、XXL-JOB