Java 定時任務技術發展歷程

語言: CN / TW / HK

定時任務是每個業務常見的需求,比如每分鐘掃描超時支付的訂單,每小時清理一次資料庫歷史資料,每天統計前一天的資料並生成報表等等。常見的解決方案有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 鎖。

image.png

五、XXL-JOB