我正在尝试使用 java spring 中的 @Scheduled 注释以固定速率执行任务。然而,默认情况下,如果任务慢于固定速率,Spring 似乎不会以固定速率执行固定速率任务。我可以在弹簧配置中添加一些设置来改变这种行为吗?
example:
@Service
public class MyTask{
@Scheduled(fixedRate = 1000)
public void doIt(){
// this sometimes takes >1000ms, in which case the next execution is late
...
}
}
我有一个解决方法,但似乎不太理想。基本上,我只是用线程池替换默认的单线程执行器,然后我有一个调度方法调用异步方法,因为 @Async 注释允许并发执行:
@Service
public class MyTask{
@Async
public void doIt(){
// this sometimes takes >1000ms, but the next execution is on time
...
}
}
@Service
public class MyTaskScheduler{
...
@Scheduled(fixedRate = 1000)
public void doIt(){
myTask.doIt();
}
}
@Configuration
@EnableScheduling
@EnableAsync
public class MySpringJavaConfig{
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.newScheduledThreadPool(5);
}
}
我的无聊细节真实场景:在我的生产代码中,我有一个任务需要 10 毫秒到 10 分钟之间的时间,具体取决于当前的工作负载。理想情况下,我希望每 1000 毫秒从池中捕获一个新线程,以便并发线程数随着工作负载的增加而增加。显然,我对线程(以及其他控件)有一个上限,以防止事情失控。
The TaskSchedulerAPI(支持一些 Spring 调度行为)似乎是为了防止您请求的行为而定义的
安排给定的Runnable
,在指定的执行时调用它
时间以及随后的给定期间。
参数
-
period连续执行任务之间的时间间隔(以毫秒为单位)
随后 and 连续似乎表明只有当前执行完成后才会进行下一次执行。
更重要的是,ScheduledExecutorService#scheduleAtFixedRate(..)(其中内置TaskScheduler
实现使用)还说
如果此任务的任何执行时间超过其周期,则
后续执行可能会延迟开始,但不会同时
执行.
因此,还有另一层实现可以阻止您想要的行为。
一种可能的解决方案是定义并提供您自己的解决方案,但我不推荐这种解决方案,因为 API 似乎不是围绕它构建的TaskScheduler
这确实同时运行任务。调查@EnableScheduling and SchedulingConfigurer了解如何注册TaskScheduler
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)