为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Spring ScheduledTaskRegistrar 进行异步调度

使用 Spring ScheduledTaskRegistrar 进行异步调度

暮色呼如 2023-06-08 20:59:28
我有问题,我想在运行时创建一个计划任务。计划任务应以固定速率触发。但现在我遇到了手动设置计划未以异步方式触发的问题。主要问题是,我们没有任何可以启动调度程序的修复点。它应该在我读取特定值 (1) 时创建,并在值变回 (0) 时被销毁。否则我们可以使用下面测试 1 中描述的注释配置。到目前为止我尝试了什么:1. 安排@Scheduled(fixedRate = 500L)和@Async代码@Async@Scheduled(fixedRate = 500L)public void annotationTest() {    UUID id = UUID.randomUUID();    log.warn("Hello from Thread {} going to sleep", id);    try {        Thread.sleep(1000L);    } catch (InterruptedException e) {        e.printStackTrace();    }    log.warn("Finished Thread {}", id);}在类级别也有@EnableAsync和注释。@EnableScheduling结果09:56:24.855 [task-5] : Hello from Thread 3b5514b2-3b80-4641-bf12-2cd320c4b6e5 going to sleep09:56:25.355 [task-6] : Hello from Thread e98514a7-e193-422b-9569-f7635deb33f8 going to sleep09:56:25.356 [task-4] : Finished Thread d86f5f24-bffb-4ddd-93fe-2334ed48cf9109:56:25.854 [task-7] : Hello from Thread cfc2ab03-4e7e-4a4a-aa08-41d696cb6df7 going to sleep09:56:25.855 [task-5] : Finished Thread 3b5514b2-3b80-4641-bf12-2cd320c4b6e509:56:26.355 [task-6] : Finished Thread e98514a7-e193-422b-9569-f7635deb33f8评论这按预期工作,但我们无法使用它,因为我们必须在运行时创建调度程序并在特定时间/输入后销毁它。2. 设置一个ScheduledTaskRegistrar代码//@Configuration@Beanpublic ScheduledTaskRegistrar scheduledTaskRegistrar() {    ScheduledTaskRegistrar scheduledTaskRegistrar = new ScheduledTaskRegistrar();    scheduledTaskRegistrar.setScheduler(threadPoolTaskScheduler());    return scheduledTaskRegistrar;}@Beanpublic TaskScheduler threadPoolTaskScheduler() {    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();    scheduler.setPoolSize(20);    return scheduler;}//@Componentpublic void printMessages() {    scheduledTaskRegistrar.scheduleFixedRateTask(new FixedRateTask(new OwnRunnable(), 500L, 0L));}还将OwnRunnable休眠 1 秒,然后打印完成文本正如我们所见,任务以同步方式运行,不符合我们的要求。
查看完整描述

1 回答

?
繁华开满天机

TA贡献1816条经验 获得超4个赞

对的,这是可能的。假设您实现 SchedulingConfigurer 的类有一个方法 doMyJob()。您可以使用 Async 注释该方法并使用 FixedRateTask 中的引用。还要注意类级别注释


@Configuration

@EnableAsync

public class MyJobConfig implements SchedulingConfigurer {


    @Override

    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

        taskRegistrar.scheduleFixedRateTask(new FixedRateTask(this::doMyJob, 500L, 0L));

    }


    @Async

    public void doMyJob() {

        try {

            Thread.sleep(1000L);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

}

希望能帮助到你


编辑


我提供了未经测试的代码。最近当我试图重新创建这个场景时,我注意到如果doMyJob在SchedulingConfigurer中,它不会是真正的异步(如果延迟是 5 秒并且作业需要 10 秒,下一个作业仅在 10 秒后运行)。但是将方法移至服务类会有所帮助。


查看完整回答
反对 回复 2023-06-08
  • 1 回答
  • 0 关注
  • 152 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信