Java 定时任务技术发展历程

2022-11-04 17:24:45 浏览数 (2)

定时任务是每个业务常见的需求,比如每分钟扫描超时支付的订单,每小时清理一次数据库历史数据,每天统计前一天的数据并生成报表等等。常见的解决方案有XXL-JOB、Spring-Task等。本篇文章着重于探讨Java 定时任务技术的发展历程。

一、Timer

java.util.Timer 是JDK原生的工具类,用于创建定时任务。

创建 java.util.TimerTask 任务,在 run 方法中实现业务逻辑。通过 java.util.Timer 进行调度,支持按照固定频率或指定Date时刻执行。所有的 TimerTask 是在同一个线程中串行执行,相互影响。也就是说,对于同一个 Timer 里的多个 TimerTask 任务,如果一个 TimerTask 任务在执行中,其它 TimerTask 即使到达执行的时间,也只能排队等待。如果有异常产生,线程将退出,整个定时任务就失败。

代码语言:javascript复制
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。

代码语言:javascript复制
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。

代码语言:javascript复制
@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

0 人点赞