例:
@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毫秒从池中捕获一个新线程,以便并发线程数随着工作量的增加而增加.显然我有一个上限(在其他控件之中),以防止事情失控.
解决方法
TaskScheduler
API(支持一些Spring Scheduling行为)似乎被定义为阻止您请求的行为
Schedule the given
Runnable
,invoking it at the specified execution
time and subsequently with the given period.Parameters
- period the interval between successive executions of the task (in milliseconds)
随后和连续似乎表明下一次执行只会在当前执行完成后发生.
更重要的是,ScheduledExecutorService#scheduleAtFixedRate(..)
(内置的TaskScheduler实现使用)也说
If any execution of this task takes longer than its period,then
subsequent executions may start late,but will not concurrently
execute.
因此,实现的另一层可以阻止您想要的行为.
一个可能的解决方案,我不建议使用,因为API似乎不是围绕它构建的,是定义并提供自己的TaskScheduler,它同时运行任务.查看@EnableScheduling
和SchedulingConfigurer
,了解如何注册TaskScheduler.
原文地址:https://www.jb51.cc/java/129420.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。