天天看點

一文教會你如何使用 Spring TaskScheduler 任務排程器

  1. 概述

在本教程中,我們将讨論 Spring 任務排程機制, TaskScheduler, 以及它的預建構實作。然後我們将探索要使用的不同觸發器。

Spring 3.0 引入了TaskScheduler*,其中包含多個可以配置在未來某個時間點運作的方法。 *TaskScheduler 還傳回 ScheduledFuture 接口的表示對象,我們可以使用它來取消計劃任務并檢查它們是否已完成。

我們需要做的就是選擇一個可運作的任務進行排程,然後選擇一個合适的排程政策。

  1. ThreadPoolTaskScheduler

ThreadPoolTaskScheduler 對于内部線程管理很有用,因為它将任務委托給 ScheduledExecutorService 并實作 TaskExecutor 接口。它的單個執行個體能夠處理異步潛在執行,以及 @Scheduled 注釋。

讓我們在 ThreadPoolTaskSchedulerConfig 中定義 ThreadPoolTaskScheduler 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)
);
           

taskScheduler 将把這個可運作的任務安排在一個已知的日期,即目前時間之後的 3 秒。

現在讓我們更深入地了解ThreadPoolTaskScheduler排程機制。

  1. 以固定延遲安排可運作任務

我們可以使用兩種簡單的機制來安排固定延遲:

3.1 在最後一次計劃執行的固定延遲後執行

讓我們配置一個任務在 1000 毫秒的固定延遲後運作:

taskScheduler.scheduleWithFixedDelay(
  new RunnableTask("Fixed 1 second Delay"), 1000);
           

RunnableTask 将始終在一次執行完成和下一次執行開始之間運作 1000 毫秒。

3.2 在特定日期的固定延遲後執行

讓我們将任務配置為在給定開始時間的固定延遲後運作:

taskScheduler.scheduleWithFixedDelay(
  new RunnableTask("Current Date Fixed 1 second Delay"),
  new Date(),
  1000);
           

RunnableTask 将在指定的執行時間被調用,其中包括 @PostConstruct 方法開始的時間,随後延遲 1000 毫秒。

  1. 以固定速率排程

有兩種簡單的機制可以以固定速率排程可運作任務。

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") , 2000);
           

RunnableTask 将在目前時間後 3000 毫秒運作。

  1. 使用 CronTrigger 進行排程

我們使用CronTrigger 來根據 cron 表達式排程任務:

taskScheduler.scheduleAtFixedRate(new RunnableTask(
  "Fixed Rate of 2 seconds"), new Date(), 3000);
           

我們可以使用提供的觸發器按照某個指定的節奏或時間表運作任務:

taskScheduler.schedule(new RunnableTask("Cron Trigger"), cronTrigger);
           

在這種情況下,RunnableTask 将在每分鐘的第 10 秒執行。

  1. 使用 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 的 return 語句之前添加兩行代碼:

periodicTrigger.setFixedRate(true);
periodicTrigger.setInitialDelay(1000);
           

我們使用 setFixedRate 方法以固定速率而不是固定延遲來排程任務。然後我們使用 setInitialDelay 方法設定第一個可運作任務運作的初始延遲。

  1. 結論

在這篇簡短的文章中,我們學習了如何使用 Spring 對任務的支援來安排可運作的任務。

我們示範了以固定延遲、固定速率并根據指定觸發器運作任務。

本文代碼可以在 GitHub 找到。

本文亦通過 NoOne 的個人部落格 發表。