天天看點

SpringBoot的定時任務串行及并發記錄

之前寫【導入較大量資料異步處理】的文章裡有提到,SpringBoot定時任務并發配置相關的,但是沒有深耕其中的原理,趁有空的時候補充了解一下。以下是之前文章提到的:

一、預設是單線程的。

二、如果要并發設定定時器并發:

①在定時器上使用@Async注解實作異步任務,并需在啟動類配合加上 @EnableAsync才會生效;

②手動設定定時任務的線程池大小:不使用@Async注解,新增啟動代碼配置類:

SpringBoot的定時任務串行及并發記錄
其實對于以上的第一點預設單線程,預設定時器都是在同一個線程池用同一個線程來處理的,即單線程,是因為在定時任務注冊類(ScheduledTaskRegistrar)裡有這樣一段源碼:任務為空的時候,建立一個單線程的線程池
SpringBoot的定時任務串行及并發記錄

然而,關于并發:

①在定時器上使用@Async注解實作異步任務,并需在啟動類配合加上 @EnableAsync這個方法:是開啟了多線程沒錯,但是任務的執行時機也不受其本身執行時間的限制,那這樣就要注意可能會出現重複本任務自身并發操作導緻資料異常了。

①新增啟動代碼配置類:

在這個類ScheduledTaskRegistrar下面是還有一個設定setTaskScheduler的方法,那我們就可以通過這個暴露的方法為定時器設定一個多線程的線程池完成并發了:

SpringBoot的定時任務串行及并發記錄
此配置兩個任務可以同時執行,同一個任務不會并發執行:對于同一個任務,上一個執行完後,再進行下一次任務。

單單文字是沒有辦法證明以上的結論的,so show me your code and test:

SpringBoot的定時任務串行及并發記錄

SpringBoot的定時任務串行及并發記錄

SpringBoot的定時任務串行及并發記錄

從執行結果可以看出,确實是不同任務間并行,同一任務串行:

SpringBoot的定時任務串行及并發記錄

附上:@EnableScheduling 加載順序,SchedulingConfigurer –> TaskScheduler –>ScheduledExecutorService