定時任務注解@Scheduled不生效問題及解決
定時任務注解@Scheduled不生效
問題描述
在用@Scheduled做定時任務的注解時,發(fā)現(xiàn)@Scheduled注解不生效。
原因分析
用能要交給spring容器的注解
比如@Component注解。
使用@EnableScheduling
啟動類里面/使用定時任務所在的類中使用@EnableScheduling 注解開啟功能,自動掃描
cron表達式寫法不對
正常寫法:@Scheduled(cron="*/10 * * * * ?")
代表10s執(zhí)行一次,每個對應的是秒 分 時 天
如果是想每天0:30執(zhí)行一次,那就是:
正常寫法:@Scheduled(cron=“0 30 0 * * ?”)
使用apollo添加配置后,apollo修改配置后不生效
在使用@Scheduled時,項目啟動時已將時間注入Spring容器中。
相當于就算是apollo改了內(nèi)容有熱加載機制,值也不會生效。
如果想生效,需要重啟服務。
@Scheduled實現(xiàn)定時任務(實現(xiàn)多個定時任務并發(fā)執(zhí)行)
@Scheduled實現(xiàn)定時任務
使用@Scheduled注解需要springboot啟動類上添加注解@EnableScheduling
@SpringBootApplication
@MapperScan(basePackages = {"com.xxx.*.mapper"})
@EnableScheduling
public class PictureProcessingAdminApplication{
public static void main(String[] args) {
SpringApplication.run(PictureProcessingAdminApplication.class, args);
}
}同個任務的同步執(zhí)行
同步執(zhí)行:等待上一次定時任務結束后才開始cron表達式時間匹配
注意:同步任務所在類必須被spring掃描所管理才行,所以需要添加@Component注解。
很多人明明在方法在添加了@Scheduled注解,但是不生效都是這個原因,定時任務所在類沒有被spring管理。
@Component
public class taskTest {
@Scheduled(cron = "0 */1 * * * ?")
public void task1(){
try {
System.out.println("任務1執(zhí)行:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis())));
Thread.sleep(65000);
System.out.println("任務1結束:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis())));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}同個任務的并發(fā)執(zhí)行
相對同步執(zhí)行來說,定時任務方法頭部增加@Async即可實現(xiàn)并發(fā)執(zhí)行,也就是嚴格按照cron表達式進行時間匹配執(zhí)行,無需等待上一次任務執(zhí)行結束。
@Component
public class taskTest {
@Async
@Scheduled(cron = "0 */1 * * * ?")
public void task1(){
try {
System.out.println("任務1執(zhí)行:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis())));
Thread.sleep(65000);
System.out.println("任務1結束:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis())));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}多個任務的同步執(zhí)行
任務使用@Scheduled
然后最重要的是,需要將springboot維護的ThreadPoolTaskScheduler定時任務線程池的長度設置為大于定時任務個數(shù)的值。然后ThreadPoolTaskScheduler默認長度為1。所以默認只有一個定時任務在跑。
源碼如下:



所以,需要將ThreadPoolTaskScheduler的長度修改即可,在項目啟動時,設置長度,替換原本springboot管理的bean即可。
@Component
public class TaskSchedulerConfig {
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(10);
return threadPoolTaskScheduler;
}
}總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringSecurity HttpSecurity 類處理流程分析
SpringSecurity在SSM項目中使用基于配置文件,通過XML標簽定義認證信息,HttpSecurity在SpringBoot中通過代碼配置實現(xiàn)與XML相同功能,詳細介紹了HttpSecurity的類結構、處理過程及其與SecurityBuilder的關系,感興趣的朋友一起看看吧2024-09-09
使用Java進行FreeMarker的web模板開發(fā)的基礎教程
這篇文章主要介紹了使用Java進行FreeMarker模板引擎開發(fā)的基礎教程,文中針對FreeMarker的網(wǎng)頁標簽用法給出了一些例子,需要的朋友可以參考下2016-03-03
SpringBoot調(diào)用第三方接口的幾種方式小結
在項目中調(diào)用第三方接口時,確實需要根據(jù)項目的技術棧、架構規(guī)范以及具體的業(yè)務需求來選擇最適合的調(diào)用方式,下面我們就介紹幾種調(diào)用第三方接口的實現(xiàn)方式以及代碼示例,需要的朋友可以參考下2024-07-07
Java中使用數(shù)組實現(xiàn)棧數(shù)據(jù)結構實例
這篇文章主要介紹了Java中使用數(shù)組實現(xiàn)棧數(shù)據(jù)結構實例,本文先是講解了實現(xiàn)棧至少應該包括以下幾個方法等知識,然后給出代碼實例,需要的朋友可以參考下2015-01-01

