Spring Boot中的并发调度方法

Meh*_*ani 3 java spring scheduled-tasks

我有一个 Spring 应用程序,其中有两个用 @Component 注释的类,在每个类中,我有一个用 @Scheduled 注释的方法,这意味着我想以固定的时间间隔运行这些方法,如下所示:

这是第一个组件,它有一个 readFirstComponent() 方法,该方法从某处读取某些内容,并且需要一段时间才能执行,@Component public class FirstComp {

@Scheduled(fixedRate = 20000 )
public void readFirstComponent() {
    // body
}
Run Code Online (Sandbox Code Playgroud)

//其他方法 }

第二个组件几乎与第一个组件执行相同的操作,

@Component
Run Code Online (Sandbox Code Playgroud)

公共类 SecondComp {

@Scheduled(fixedRate = 20000 )
public void readSecondComponent() {
    // body
}
Run Code Online (Sandbox Code Playgroud)

//其他方法 }

我有一个运行程序类来启动应用程序

@SpringBootApplication
@EnableScheduling
@ImportResource("classpath:spring/Spring-AutoScan.xml")
public class Application {
public static void main(final String args[]) {
    SpringApplication.run(Application.class);    
}
Run Code Online (Sandbox Code Playgroud)

}

当我启动应用程序时,FirtComp 正在启动,readFirstComponent() 在近 14 秒后执行,然后来自 SecondComp 的 readSecondComponent() 正在启动,依此类推,我的问题是我想同时启动这两种方法,请帮助我解决这个问题

evk*_*vkm 5

默认情况下只有一个线程来运行调度任务。

您可以在此处阅读相关内容,并了解如何配置调度程序以获得具有更多线程的池。

27.4.1 启用调度注释

要启用对 @Scheduled 和 @Async 注释的支持,请将 @EnableScheduling 和 @EnableAsync 添加到 @Configuration 类之一:

@Configuration
@EnableAsync
@EnableScheduling
public class AppConfig {
}
Run Code Online (Sandbox Code Playgroud)

您可以自由挑选适合您的应用程序的相关注释。例如,如果您只需要支持@Scheduled,则只需省略@EnableAsync即可。为了进行更细粒度的控制,您可以另外实现 SchedulingConfigurer 和/或 AsyncConfigurer 接口。有关完整详细信息,请参阅 javadoc。

如果您更喜欢 XML 配置,请使用该元素。

<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>
Run Code Online (Sandbox Code Playgroud)

请注意,上面的 XML 提供了执行程序引用来处理与带有 @Async 注释的方法相对应的任务,并提供了调度程序引用来管理那些用 @Scheduled 注释的方法。

由于您使用注释来配置 bean,因此最好使用implement the SchedulingConfigurer.

像这样:

@Configuration
@EnableScheduling
public class SchedulingConfig implements SchedulingConfigurer {

@Override
public void configureTasks(
  ScheduledTaskRegistrar taskRegistrar) {
    taskRegistrar.setScheduler(taskExecutor());
}

@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
    return Executors.newScheduledThreadPool(10);
}
}
Run Code Online (Sandbox Code Playgroud)