在啓動類上添加註解 @EnableScheduling
html
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
複製代碼
在須要實現定時任務的方法上添加註解 @Scheduled
。java
@Component
public class MySchedule {
@Scheduled(cron = "0/10 * * * * *")
public void test() throws InterruptedException {
log.info(Thread.currentThread().getName()+"---test");
TimeUnit.SECONDS.sleep(12);
}
}
複製代碼
Schedule 主要有三種調度方式:fixedRate、fixedDelay、cron表達式。spring
固定頻率任務。segmentfault
該屬性的含義是上一個調用開始後再次調用的延時(不用等待上一次調用完成),這樣就可能會存在任務重複執行的問題,因此不是建議使用,但數據量若是不大時在配置的間隔時間內能夠執行完也是可使用的。springboot
注意:當方法的執行時間超過任務調度頻率時,調度器會在當前方法執行完成後當即執行下次任務。bash
@Scheduled(fixedRate = 1000 * 10)
public void work() {
// do your work here
}
複製代碼
fixedRate 的單位是毫秒,上例中 fixedRate = 1000 * 10
表示每 10 秒執行一次。ui
設第一次執行開始時時間爲 0,正常狀況下第二次執行開始時間是第 10 秒,第三次是第 20 秒……以此類推。spa
但假如任務在 10 秒內沒有完成,好比第一次花了 15秒完成任務,那第二次執行時間也是 第15 秒,會立刻執行。線程
固定間隔任務。code
下一次的任務執行時間,是從方法最後一次任務執行結束時間開始計算。並以此規則開始週期性的執行任務。
@Scheduled(fixedDelay = 1000 * 10)
public void work() {
// do your work here
}
複製代碼
上例每隔10秒執行一次,設第一次執行開始時時間爲 0,若是任務的執行時間是 5 秒,那下次任務的開始時間是 5 + 10 = 15
即第 15 秒。再下一次任務開始執行時間是 15 + 5 + 10 = 30
即第 30 秒,以此類推。
Cron表達式由6或7個空格分隔的時間字段組成,以下圖:
* 第一位,表示秒,取值 0-59
* 第二位,表示分,取值 0-59
* 第三位,表示小時,取值 0-23
* 第四位,日期,取值 1-31
* 第五位,月份,取值 1-12
* 第六位,星期幾,取值 1-7
* 第七位,年份,能夠留空,取值 1970-2099
(*) 星號:能夠理解爲「每」的意思,每秒、沒分
(?) 問號:只能出如今日期和星期這兩個位置,表示這個位置的值不肯定
(-) 表達一個範圍,如在小時字段中使用 10-12 ,表示從10點到12點
(,) 逗號,表達一個列表值,如在星期字段中使用 1,2,4 ,則表示星期1、星期2、星期四
(/) 斜槓,如 x/y ,x是開始值,y是步長,如在第一位(秒)使用 0/15,表示從0秒開始,每15秒
官方解釋:
0 0 3 * * ? 天天 3 點執行
0 5 3 * * ? 天天 3 點 5 分執行
0 5 3 ? * * 天天 3 點 5 分執行
0 5/10 3 * * ? 天天 3 點 5 分,15 分,25 分,35 分,45 分,55 分這幾個點執行
0 10 3 ? * 1 每週星期天的 3 點10 分執行,注:1 表示星期天
0 10 3 ? * 1 #3 每月的第三個星期的星期天 執行,#號只能出如今星期的位置
注:第六位(星期幾)中的數字可能表達不太正確,可使用英文縮寫來表示,如:Sun
複製代碼
注意,當方法的執行時間超過任務調度頻率時,調度器會在下個週期執行。
下面的例子,每 10 秒執行一次,但任務執行時間是 12 秒。
設第一次執行任務開始時間是 0,那第一次任務執行完應該是第 12 秒。第二次任務本應在第 10 秒開始執行,但因爲第 10 秒時第一次任務還沒執行完,因此第二次任務會把第 10 秒這個節點跳過,等到第 20 秒再執行第二次任務。
@Scheduled(cron = "0/10 * * * * *")
public void test() throws InterruptedException {
log.info(Thread.currentThread().getName()+"---test");
TimeUnit.SECONDS.sleep(12);
}
複製代碼
Spring 會默認建立一個單線程池,若是系統中有多個定時任務要執行,任務調度器就會出現時間漂移,任務執行時間將不肯定。
因此咱們自定義一個 TaskScheduler 線程池。
@Configuration
public class InitBeanConfig {
/** * 配置 Schedule 的線程池. */
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
taskScheduler.setThreadNamePrefix("springboot-task");
return taskScheduler;
}
}
複製代碼
這樣當須要同時執行多個任務,就會最多開啓 10 個線程來處理。
參考文章:
以上就是 SpringBoot 集成 Schedule 的所有內容,後續開發中遇到相關問題會繼續更新,歡迎關注。