首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于Spring ScheduledTaskRegistrar的异步调度

基于Spring ScheduledTaskRegistrar的异步调度
EN

Stack Overflow用户
提问于 2019-08-19 09:20:29
回答 1查看 3.7K关注 0票数 5

我有一个问题,我想要在运行时创建一个预定的任务。计划的任务应该以固定的速率触发。但是,现在我遇到的问题是手动设置计划不是以异步方式触发的。

主要的问题是,如果我们可以启动调度程序,那么我们就没有任何固定点。当我读取一个特定的值(1)时,应该创建它,并在值更改回(0)时销毁它。否则,我们可以使用下面测试1中描述的注释配置。

到目前为止,我已经尝试过:

1. @Scheduled(fixedRate = 500L) @Async的日程安排

代码

代码语言:javascript
复制
@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注释。

结果

代码语言:javascript
复制
09:56:24.855 [task-5] : Hello from Thread 3b5514b2-3b80-4641-bf12-2cd320c4b6e5 going to sleep
09:56:25.355 [task-6] : Hello from Thread e98514a7-e193-422b-9569-f7635deb33f8 going to sleep
09:56:25.356 [task-4] : Finished Thread d86f5f24-bffb-4ddd-93fe-2334ed48cf91
09:56:25.854 [task-7] : Hello from Thread cfc2ab03-4e7e-4a4a-aa08-41d696cb6df7 going to sleep
09:56:25.855 [task-5] : Finished Thread 3b5514b2-3b80-4641-bf12-2cd320c4b6e5
09:56:26.355 [task-6] : Finished Thread e98514a7-e193-422b-9569-f7635deb33f8

评论

这可以像预期的那样工作,但是我们无法使用它,因为我们必须在运行时创建调度程序,并在特定的时间/输入之后销毁它。

ScheduledTaskRegistrar 2.设置

代码

代码语言:javascript
复制
//@Configuration

@Bean
public ScheduledTaskRegistrar scheduledTaskRegistrar() {
    ScheduledTaskRegistrar scheduledTaskRegistrar = new ScheduledTaskRegistrar();
    scheduledTaskRegistrar.setScheduler(threadPoolTaskScheduler());
    return scheduledTaskRegistrar;
}

@Bean
public TaskScheduler threadPoolTaskScheduler() {
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
    scheduler.setPoolSize(20);
    return scheduler;
}

//@Component

public void printMessages() {
    scheduledTaskRegistrar.scheduleFixedRateTask(new FixedRateTask(new OwnRunnable(), 500L, 0L));
}

OwnRunnable还将休眠1秒,然后打印完成的文本。

结果

代码语言:javascript
复制
10:13:56.983 [TaskScheduler-1] : Finished Thread 73f70de9-35d9-47f0-801b-fb2857ab1c34
10:13:56.984 [TaskScheduler-3] : Hello from Thread 7ab16380-8dba-49e1-bf0d-de8235f81195 going to sleep
10:13:57.984 [TaskScheduler-3] : Finished Thread 7ab16380-8dba-49e1-bf0d-de8235f81195
10:13:57.984 [TaskScheduler-2] : Hello from Thread cc152d2e-f93b-4770-ac55-853a4dd6be97 going to sleep
10:13:58.985 [TaskScheduler-2] : Finished Thread cc152d2e-f93b-4770-ac55-853a4dd6be97
10:13:58.985 [TaskScheduler-4] : Hello from Thread 8d4510a4-773d-49f3-b51b-e58e425b0b68 going to sleep

评论

正如我们所看到的,这些任务以同步的方式运行,不适合我们的需求。

3.其他测试

所有其他测试都类似于2中描述的测试,但将使用ScheduledTaskRegistrar的其他一些配置。结果与测试2相同。

  • ConcurrentTaskScheduler而不是ThreadPoolTaskScheduler
  • ConcurrentTaskSchedulerSimpleAsyncTaskExecutorConcurrentExecutor
  • ConcurrentTaskSchedulerThreadPoolTaskExecutorConcurrentExecutor

问题

如何使用测试2中描述的配置,但得到测试1的结果?有办法在测试2中描述的解决方案中使用@Async注释吗?还是有人对我的问题有更好的解决方案?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-01 19:48:18

是的,这是可能的。假设实现SchedulingConfigurer的类有一个方法doMyJob()。可以使用异步对该方法进行注释,并在FixedRateTask中使用该引用。还请注意类级注释。

代码语言:javascript
复制
@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();
        }
    }
}

希望它能帮上忙

编辑

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57553786

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档