我有几种用注释的方法@Scheduled(fixedDelay=10000)
。
在应用程序上下文中,我具有以下注释驱动的设置:
<task:annotation-driven />
问题是,有时某些方法的执行会延迟几秒钟甚至几分钟。
我假设即使某个方法需要一段时间才能完成执行,其他方法仍将执行。所以我不明白延迟。
有没有办法减少甚至消除延迟?
Answers:
为了完整起见,以下代码显示了使用java config配置调度程序的最简单方法:
@Configuration
@EnableScheduling
public class SpringConfiguration {
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.newScheduledThreadPool(5);
}
...
当需要更多控制时,@Configuration
可以实现一个类SchedulingConfigurer
。
<task:scheduler id="taskScheduler" pool-size="5"/>
带有注解的方法@Scheduled
应在某个时间在不同线程上分别运行。
如果您未TaskScheduler
在配置中提供,Spring将使用
Executors.newSingleThreadScheduledExecutor();
它返回ScheduledExecutorService
在单个线程上运行的。这样,如果您有多个@Scheduled
方法,尽管它们是已调度的,但每个方法都需要等待线程完成执行上一个任务。由于队列填满的时间快于清空的时间,因此延迟可能会越来越大。
确保使用适当数量的线程配置调度环境。
@Scheduled
(和@EnableScheduling
)通过注册来处理ScheduledAnnotationBeanPostProcessor
。该后处理器使用ScheduledTaskRegistrar
默认为该单线程的ScheduledExecutorService
。
该@EnableScheduling注释提供了关键信息,以及如何解决它:
默认情况下,将搜索关联的调度程序定义:上下文中的唯一TaskScheduler Bean,否则为名为“ taskScheduler”的TaskScheduler Bean;对于ScheduledExecutorService bean也将执行相同的查找。如果二者都不可解析,则将在注册器中创建并使用本地单线程默认调度程序。
当需要更多控制时,@Configuration类可以实现SchedulingConfigurer。这允许访问基础ScheduledTaskRegistrar实例。例如,以下示例演示了如何自定义用于执行计划任务的执行器:
@Configuration
@EnableScheduling
public class AppConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(100);
}
}
(添加了重点)
使用XML文件添加以下行。
<task:scheduler id="taskScheduler" pool-size="15" />
<task:scheduled-tasks scheduler="taskScheduler" >
....
</task:scheduled-tasks>
Executor
接口没有shutdown()
方法,所以我认为最好使用ExecutorService
返回类型来使Bean定义正确。还是Spring会在运行时发现实际的bean类型?