Java Spring的调度程序中的异步任务

发布于 2025-02-10 16:15:35 字数 1440 浏览 1 评论 0原文

我目前在春季应用程序中有一个计划的任务。

但是,这种逻辑的两个部分非常耗时,我想知道是否有一种使这两个部分异步的方法,以免干扰执行逻辑的时间。

我需要执行如下的逻辑。

@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);
            }

        }
    }

从我的理解来看,调度程序已经异步执行逻辑,我想知道是否有任何方法可以使这两个块异步使其在执行此逻辑时不会导致延迟。

I currently have a scheduled task within my Spring application.

However a two parts of this logic is severely time-consuming and I am wondering if there would be a way to make these two parts asynchronous so that it does not interfere with the time of the logic being executed.

The logic that I need to execute as follows.

@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);
            }

        }
    }

From my understanding, a scheduler already is executing logic asynchronously, and I wonder if there would be any way of making those two blocks asynchronous so that it does not cause delays when executing this logic.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

素年丶 2025-02-17 16:15:35

您可以在这里采用几种方法。

默认情况下为Spring的计划任务配置线程池执行程序,

Spring使用单线程执行程序来执行计划的任务,这意味着即使您有多个@scheduled任务> 任务或在上一个任务触发之前执行的另一个执行完成后,他们都必须在队列中等待。

您可以配置自己的执行程序,以通过春季计划使用。看看 @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

执行计划的任务

既可以执行计划的任务,则可以不断地执行计划的任务。春季的@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();
    }
}

There are several approaches that you could take here.

Configuring Thread Pool executor for Spring's scheduled tasks

By default Spring uses single thread executor to execute scheduled tasks, which means that even if you have multiple @Scheduled tasks or another execution for a task triggers before the previous one is completed, they will all have to wait in the queue.

You can configure your own executor to be used by Spring Scheduling. Take a look at the documentation of @EnableScheduling, it is pretty exhaustive on the subject.

To configure ExecutorService to be used for scheduled tasks it is enough to define a bean:

@Bean
public TaskScheduler  taskScheduler() {
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(8);
    threadPoolTaskScheduler.setThreadNamePrefix("task-scheduler");
    return threadPoolTaskScheduler;
}

Additionally, if you use Spring Boot, you can use properties file:

spring.task.scheduling.pool.size=8

Executing scheduled tasks asynchronously

To execute scheduled tasks asynchronously you can use Spring's @Async annotation (and make sure to @EnableAsync somewhere in your configuration. That will make your tasks to be executed on a background thread, freeing the scheduling thread.

@EnableAsync
public class ScheduledAsyncTask {

    @Async
    @Scheduled(fixedRate = 10000)
    public void scheduleFixedRateTaskAsync() throws InterruptedException {
        // your task logic ...
    }
}

Offload expensive parts of your tasks to a different executor

Finally, you could use a separate ExecutorService and run expensive parts of your tasks using that executor instead of the one used for task scheduling. This will keep the time needed to complete the execution on the thread used by Spring to schedule tasks to a minimum, allowing it to start next executions.

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文