簡體   English   中英

Java Spring調度程序中的異步任務

[英]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 的計划任務配置線程池執行器

默認情況下,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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM