春季预定的固定利率无法正常工作

2023-12-27

正如标题所示,我尝试使用 Scheduled 注释的固定 Rate 参数来每秒调用一个函数。这是我正在使用的代码:

  //execute once every second
  @Scheduled(fixedRate = 1000)
  private void pullLiveDataFromExternalServer() throws InterruptedException {

    System.err.println("START THREAD " + Thread.currentThread().getId());
    Thread.sleep(5500L);
    System.err.println("END THREAD " + Thread.currentThread().getId());

  }

据我理解,该函数应该在打印第一个“END THREAD”之前打印“START THREAD”五次。

问题是该函数首先打印“START THREAD”,然后等待 5.5 秒,打印“END THREAD”,然后进入“START THREAD”等等......看起来调度程序等待上一个执行完成之前它会启动新的执行,但固定速率属性不应出现这种情况。

我仔细阅读了一下,发现 @Scheduled 注释的默认调度程序只有一个线程,因此我创建了一个配置将池大小更改为 8。

@Component
public class SchedulingConfigurerConfiguration implements SchedulingConfigurer {
  @Override
  public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    taskScheduler.setPoolSize(8);
    taskScheduler.initialize();
    taskRegistrar.setTaskScheduler(taskScheduler);
  }
}

但是,fixedRate 属性的行为没有改变,调度程序仍在等待上一次执行结束,然后再开始新的执行。为什么会出现这种情况?

我使用的 Spring Boot 版本是 v1.5.8.RELEASE。


看起来调度程序会等待上一个执行完成后再开始新的执行

这是正确的,也是预期的行为。每个计划任务,无论fixedRate or fixedDelay,永远不会并行运行。即使调用时间比配置的时间长,情况也是如此fixedRate.

最终,固定速率调度导致调用ScheduledExecutorService.scheduleAtFixedRate。其 javadoc 声明如下:

如果此任务的任何执行时间超过其周期,则后续执行可能会延迟开始,但不会同时执行。

如果同一计划任务的多个调用可以并行运行,那么您问题中的示例将耗尽所有可用线程。每 1000 毫秒就会使用一个新线程,并且每 5500 毫秒才会有一个线程再次可用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

春季预定的固定利率无法正常工作 的相关文章

随机推荐