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