1. 概述
本教程將討論 Spring 任務調度機制、TaskScheduler 及其預構建的實現。 此外,我們還將探索可用的不同觸發器。 要了解更多關於 Spring 中任務調度的信息,請查看以下 @Async 和 @Scheduled 文章。
Spring 3.0 引入了 TaskScheduler,並提供了多種方法,用於在未來某個時間點運行任務。 TaskScheduler 還返回 ScheduledFuture 接口的表示對象,我們可以使用它來取消已安排的任務並檢查它們是否已完成。
我們只需要選擇一個可用於安排的執行任務,然後選擇合適的調度策略。
2. <em>ThreadPoolTaskScheduler</em>
<em>ThreadPoolTaskScheduler</em> 適用於內部線程管理,因為它將任務委派給 <em>ScheduledExecutorService</em>,並實現了 <em>TaskExecutor</em> 接口。 單個實例能夠處理異步執行的可能性,以及 @Scheduled 註解。
讓我們在 <em>ThreadPoolTaskSchedulerConfig</em> 中定義 <em>ThreadPoolTaskScheduler</em> Bean:
@Configuration
@ComponentScan(
basePackages="com.baeldung.taskscheduler",
basePackageClasses={ThreadPoolTaskSchedulerExamples.class})
public class ThreadPoolTaskSchedulerConfig {
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
ThreadPoolTaskScheduler threadPoolTaskScheduler
= new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(5);
threadPoolTaskScheduler.setThreadNamePrefix(
"ThreadPoolTaskScheduler");
return threadPoolTaskScheduler;
}
}配置的 Bean threadPoolTaskScheduler 可以根據配置的池大小(5)異步執行任務。
請注意,所有 ThreadPoolTaskScheduler 相關的線程名稱都將以 ThreadPoolTaskScheduler 為前綴。
讓我們實現一個簡單的任務,然後安排它:
class RunnableTask implements Runnable{
private String message;
public RunnableTask(String message){
this.message = message;
}
@Override
public void run() {
System.out.println(new Date()+" Runnable Task with "+message
+" on thread "+Thread.currentThread().getName());
}
}
我們現在可以安排調度器執行此任務:
taskScheduler.schedule(
new Runnabletask("Specific time, 3 Seconds from now"),
new Date(System.currentTimeMillis + 3000)
);
任務調度器將在已知日期,當前時間後精確 3 秒後安排該可運行任務。
現在,讓我們更深入地探討線程池任務調度器的調度機制。
3. 使用固定延遲安排可執行任務
我們可以使用兩個簡單的機制來安排固定延遲:
3.1. 在上次執行完成後進行調度
讓我們配置一個任務在 1000 毫秒的固定延遲後運行:
taskScheduler.scheduleWithFixedDelay(
new RunnableTask("Fixed 1 second Delay"), 1000);可執行任務將在一個執行完成與下一個執行開始之間始終延遲1000毫秒。
3.2. 在特定日期固定延遲後安排任務
讓我們配置一個任務在給定起始時間後執行:
taskScheduler.scheduleWithFixedDelay(
new RunnableTask("Current Date Fixed 1 second Delay"),
new Date(),
1000);可執行任務將在指定執行時間觸發,該時間包括@PostConstruct方法啓動的時間,隨後再延遲1000毫秒。
4. 以固定速率調度
有兩項簡單的機制可用於以固定速率調度可運行的任務。
4.1. 以固定速率安排 RunnableTask
讓我們安排一個任務以 固定毫秒速率 運行:
taskScheduler.scheduleAtFixedRate(
new RunnableTask("Fixed Rate of 2 seconds") , 2000);下個 RunnableTask 將始終在 2000 毫秒後執行,與上一次執行的狀態無關,後者可能仍在運行中。
4.2. 從指定日期以固定速率安排 RunnableTask
taskScheduler.scheduleAtFixedRate(new RunnableTask(
"Fixed Rate of 2 seconds"), new Date(), 3000);可執行任務將在當前時間後 3000 毫秒後執行。
5. 使用 CronTrigger 安排任務
我們使用 CronTrigger 根據 cron 表達式安排任務:
CronTrigger cronTrigger
= new CronTrigger("10 * * * * ?");
我們可以使用提供的觸發器來根據指定的節奏或時間表運行任務:
taskScheduler.schedule(new RunnableTask("Cron Trigger"), cronTrigger);在這種情況下,RunnableTask 將在每分鐘的第 10 秒執行。
6. 使用 PeriodicTrigger 定時任務
讓我們使用 PeriodicTrigger 來安排一個任務,其固定延遲為 2000 毫秒:
PeriodicTrigger periodicTrigger
= new PeriodicTrigger(2000, TimeUnit.MICROSECONDS);配置的 PeriodicTrigger Bean 用於在 2000 毫秒的固定延遲後運行一個任務。
現在,讓我們使用 PeriodicTrigger 調度 RunnableTask:
taskScheduler.schedule(
new RunnableTask("Periodic Trigger"), periodicTrigger);我們還可以配置 PeriodicTrigger 在固定的速率下進行初始化,而不是固定的延遲。 此外,我們還可以通過給定的毫秒數設置首次計劃任務的初始延遲。
我們只需要在返回值語句之前添加兩行代碼,在 periodicTrigger Bean 中:
periodicTrigger.setFixedRate(true);
periodicTrigger.setInitialDelay(1000);我們使用 setFixedRate 方法來按固定速率安排任務,而不是使用固定延遲。然後,我們使用 setInitialDelay 方法為第一個可運行的任務設置初始延遲。
7. 結論
在本文中,我們學習瞭如何使用 Spring 支持的任務功能來安排可執行的任務。
我們演示了使用固定延遲、固定速率和指定觸發器來運行任務的方法。