springboot 并发执行定时任务
生活随笔
收集整理的這篇文章主要介紹了
springboot 并发执行定时任务
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在使用springboot框架時,其注解使用大大提升了我們的編程效率。定時任務可以通過@Scheduled注解實現。
但是該方法存在一個缺點:多個定時任務使用的是同一個調度線程,所以定時任務是阻塞執行的,執行效率不高。比如20:00的任務需要執行2個小時,而恰好你在21:00需要執行另一個任務,那在21:00的任務會被阻塞到22:00進行,可能會導致執行結果不是我們想要的。
通過查看springboot底層代碼:
//默認的調度器 if (this.taskScheduler == null) {this.localExecutor = Executors.newSingleThreadScheduledExecutor();this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor); }//可以看到默認指定的核心線程數為1,也就是單線程 public static ScheduledExecutorService newSingleThreadScheduledExecutor() {return new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1)); }解決方法:通過配置類直接重新配置定時任務的調度器,增加其線程數,實現定時任務的并發執行。
//定時任務配置類 @Configuration public class ScheduledConfig implements SchedulingConfigurer {@Autowiredprivate TaskScheduler myThreadPoolTaskScheduler;@Overridepublic void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {//直接暴力指定線程數//scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));//自定義線程池scheduledTaskRegistrar.setTaskScheduler(myThreadPoolTaskScheduler);}} //自定義線程池 @Component public class TaskScheduler {@Bean(name = "myThreadPoolTaskScheduler")public ThreadPoolTaskScheduler getMyThreadPoolTaskScheduler() {ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();taskScheduler.setPoolSize(10);taskScheduler.setThreadNamePrefix("myScheduled-");//拒絕策略 callerRunsPolicy-由調用線程處理該任務taskScheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());//調度器shutdown被調用時等待當前被調度的任務完成,用來設置線程池關閉的時候等待所有任務都完成再繼續銷毀其他的Bean。同時,還設置了setAwaitTerminationSeconds(60),該方法用來設置線程池中任務的等待時間,如果超過這個時候還沒有銷毀就強制銷毀,以確保應用最后能夠被關閉,而不是阻塞住。taskScheduler.setWaitForTasksToCompleteOnShutdown(true);taskScheduler.setAwaitTerminationSeconds(60);return taskScheduler;}}總結
以上是生活随笔為你收集整理的springboot 并发执行定时任务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 生成组织列表树(非递归)
- 下一篇: 跨源资源共享(CORS)漏洞修复