文章目錄
- 1.@Scheduled注解定義
- 2.配置 @Scheduled
- 2.1 開啟定時任務支持
- 2.2 創建定時任務
- 3. 常用屬性
- 3.1 fixedRate
- 3.2 fixedDelay
- 3.3 cron
- 4.工作原理
- 4.1 基于TaskScheduler
- 4.2 使用 ThreadPoolTaskScheduler
- 4.3 定時任務的執行流程
- 5. 延時執行的定時任務
- 5.1 創建定時任務類
- 5.2 解釋
- 6.自定義TaskScheduler
1.@Scheduled注解定義
簡單來說, @Scheduled
是 Spring 提供的一個注解,用于在方法上標記定時任務。通過它,我們可以輕松地在指定的時間間隔或特定的時間點執行某些代碼,而不需要引入額外的定時任務庫。
舉個例子:
假設你有一個方法需要每隔5分鐘執行一次,你只需要在方法上加上 @Scheduled
注解,并設置相應的屬性即可。
2.配置 @Scheduled
在開始使用 @Scheduled
之前,我們需要做一些配置工作。首先,確保你的 Spring 項目中引入了 spring-boot-starter
,因為它已經包含了必要的依賴。
2.1 開啟定時任務支持
在你的主類(通常標注了 @SpringBootApplication
的類)上添加@EnableScheduling
注解,以啟用定時任務的支持。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication
@EnableScheduling
public class ScheduledDemoApplication {public static void main(String[] args) {SpringApplication.run(ScheduledDemoApplication.class, args);}
}
2.2 創建定時任務
接下來,我們創建一個服務類,并在其中定義一個定時任務方法。例如,每隔5秒打印一條消息:
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;@Component
public class ScheduledTasks {@Scheduled(fixedRate = 5000)public void reportCurrentTime() {System.out.println("每5秒執行一次任務,當前時間:" + System.currentTimeMillis());}
}
3. 常用屬性
@Scheduled
注解提供了多種方式來配置定時任務的執行時間,主要包括以下幾種
3.1 fixedRate
指定一個固定的時間間隔,以毫秒為單位,表示上一次任務開始執行后,多久再次執行。
@Scheduled(fixedRate = 5000) // 每5秒執行一次
public void fixedRateTask() {System.out.println("Fixed Rate Task - " + System.currentTimeMillis());
}
3.2 fixedDelay
指定一個固定的時間間隔,表示上一次任務執行完成后,等待多久再次執行。
@Scheduled(fixedDelay = 5000) // 上一次任務完成后5秒執行一次
public void fixedDelayTask() {System.out.println("Fixed Delay Task - " + System.currentTimeMillis());
}
3.3 cron
使用 cron 表達式確地指定任務的執行時間。cron 表達式可以讓你定義復雜的時間計劃。
@Scheduled(cron = "0 0/1 * * * ?") // 每分鐘執行一次
public void cronTask() {System.out.println("Cron Task - " + System.currentTimeMillis());
}
4.工作原理
了解了如何使用 @Scheduled
,那么它背后到底是如何運作的呢?讓我們來深入探討一下。
4.1 基于TaskScheduler
Spring 的定時任務是基于 TaskScheduler 接口實現的。當我們在方法上使用 @Scheduled 注解時,Spring 會自動為其創建一個調度器,并按照我們定義的時間計劃來執行任務
4.2 使用 ThreadPoolTaskScheduler
默認情況下,Spring 使用 ThreadPoolTaskScheduler
作為TaskScheduler
的實現類。它內部維護了一個線程池,用于執行定時任務。這樣可以確保多個定時任務能夠并發執行,而不會阻塞主線程。
注意: 如果你的應用中有多個定時任務,或者某些任務執行時間較長,建議自定義ThreadPoolTaskScheduler
的線程池大小,以避免任務堆積或資源浪費。
4.3 定時任務的執行流程
1、初始化階段:
啟動 Spring 應用時,@EnableScheduling 注解會觸發 Spring 的配置,掃描所有被 @Scheduled 注解標記的方法。
2、注冊任務:
所有符合條件的定時任務方法會被注冊到 TaskScheduler 中。
3、執行任務:
根據配置的時間計劃,TaskScheduler 會調度并在合適的線程中執行相應的任務方法。
5. 延時執行的定時任務
為了更好地理解 @Scheduled
的使用,我們來實現一個稍微復雜些的示例——延時執行任務。假設我們有一個任務需要在應用啟動后延時10秒執行一次,然后每隔5秒重復執行。
5.1 創建定時任務類
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;@Component
publicclass DelayedScheduledTasks {privateboolean firstRun = true;@Scheduled(fixedRate = 5000, initialDelay = 10000)public void delayedTask() {if (firstRun) {System.out.println("延時10秒后首次執行任務,當前時間:" + System.currentTimeMillis());firstRun = false;} else {System.out.println("每5秒執行一次任務,當前時間:" + System.currentTimeMillis());}}
}
5.2 解釋
fixedRate = 5000
: 任務每5秒執行一次。
initialDelay = 10000
: 應用啟動后,延時10秒首次執行任務。
6.自定義TaskScheduler
有時候,默認的 ThreadPoolTaskScheduler
可能無法滿足我們的需求,比如需要更高的并發能力或特定的線程名稱模式。這時候,我們可以自定義一個 TaskScheduler Bean
。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;@Configuration
publicclass SchedulerConfig {@Beanpublic ThreadPoolTaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(10); // 設置線程池大小scheduler.setThreadNamePrefix("MyScheduler-"); // 設置線程名稱前綴scheduler.initialize();return scheduler;}
}
通過上述配置,我們創建了一個擁有10個線程的線程池,并為每個線程命名,方便日志追蹤和調試。
編輯:玄魄靈歸