[英]Asynchronous task within scheduler in Java Spring
@Scheduled(fixedDelay = 10000)
public void startAuction() throws Exception {
List<SchGoodsAuctionStartListRes> list = schedulerService.schGoodsAuctionStartList();
for (SchGoodsAuctionStartListRes item : list) {
schedulerService.schGoodsAuctionStart(item);
// 1st time consuming block that needs async
PushInfo pushInfo = pushMapper.pushGoodsSeller(item.getGoodsIdx());
pushInfo.setTitle("Start");
pushInfo.setBody("[" + pushInfo.getBrand() + "] started.");
pushInfo.setPushGrp("001");
pushInfo.setPushCode("003");
fcmPushUtil.sendPush(pushInfo);
// 2nd time consuming block that needs async
List<PushInfo> pushInfos = pushMapper.pushGoodsAuctionAll(item.getIdx());
for (PushInfo pushInfoItem : pushInfos) {
pushInfoItem.setTitle("\uD83D\uDD14 open");
pushInfoItem.setBody("[" + pushInfo.getBrand() + "] started. \uD83D\uDC5C");
pushInfoItem.setPushGrp("002");
pushInfoItem.setPushCode("008");
fcmPushUtil.sendPush(pushInfoItem);
}
}
}
您可以在此處采用多種方法。
默認情況下,Spring 使用單線程執行器來執行計划任務,這意味着即使您有多個@Scheduled
任務,或者在前一個任務完成之前觸發另一個任務的執行,它們都必須在隊列中等待。
您可以配置自己的執行程序以供 Spring 調度使用。 看一下@EnableScheduling
的文檔,它在這個主題上非常詳盡。
要將ExecutorService
配置為用於計划任務,定義一個 bean 就足夠了:
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(8);
threadPoolTaskScheduler.setThreadNamePrefix("task-scheduler");
return threadPoolTaskScheduler;
}
此外,如果您使用 Spring Boot,則可以使用屬性文件:
spring.task.scheduling.pool.size=8
要異步執行計划任務,您可以使用 Spring 的@Async
注釋(並確保在配置中的某處使用@EnableAsync
。這將使您的任務在后台線程上執行,從而釋放調度線程。
@EnableAsync
public class ScheduledAsyncTask {
@Async
@Scheduled(fixedRate = 10000)
public void scheduleFixedRateTaskAsync() throws InterruptedException {
// your task logic ...
}
}
最后,您可以使用單獨的ExecutorService
並使用該執行器而不是用於任務調度的執行器來運行任務的昂貴部分。 這將使 Spring 用於調度任務的線程上完成執行所需的時間保持在最低限度,從而允許它開始下一次執行。
public class ScheduledAsyncTask implements DisposableBean {
private final ExecutorService executorService = Executors.newFixedThreadPool(4);
@Scheduled(fixedRate = 10000)
public void scheduleFixedRateTaskAsync() throws InterruptedException {
executorService.submit(() -> {
// Expensive calculations ...
});
}
@Override
public void destroy() {
executorService.shutdown();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.