Java spring@Scheduled注释方法是否在不同的线程上运行?
我有几个用Java spring@Scheduled注释方法是否在不同的线程上运行?,java,spring,scheduled-tasks,Java,Spring,Scheduled Tasks,我有几个用@Scheduled(fixedDelay=10000)注释的方法 在应用程序上下文中,我有以下注释驱动的设置: <task:annotation-driven /> 问题是,有时一些方法的执行会延迟几秒钟甚至几分钟 我假设,即使一个方法需要一段时间才能完成执行,其他方法仍然会执行。所以我不理解延迟 有没有办法减少甚至消除延迟?一个用@Scheduled注释的方法意味着在不同的线程上同时单独运行 如果您的配置中没有提供任务调度器,Spring将使用 Executors
@Scheduled(fixedDelay=10000)
注释的方法
在应用程序上下文中,我有以下注释驱动的设置:
<task:annotation-driven />
问题是,有时一些方法的执行会延迟几秒钟甚至几分钟
我假设,即使一个方法需要一段时间才能完成执行,其他方法仍然会执行。所以我不理解延迟
有没有办法减少甚至消除延迟?一个用
@Scheduled
注释的方法意味着在不同的线程上同时单独运行
如果您的配置中没有提供任务调度器
,Spring将使用
Executors.newSingleThreadScheduledExecutor();
它返回在单个线程上运行的ScheduledExecutorService
。同样地,如果您有多个@Scheduled
方法,尽管它们是被调度的,但它们都需要等待线程完成前一个任务的执行。随着队列的填充速度快于清空速度,您可能会持续获得越来越大的延迟
确保使用适当数量的线程配置调度环境。说明:
如果不提供池大小属性,则默认线程池将只有一个线程
因此,如果您有许多计划的任务,您应该按照文档中的说明配置调度程序,使其拥有一个包含更多线程的池,以确保一个长任务不会延迟所有其他任务。为了完整性,下面的代码显示了使用java config配置调度程序的最简单方法:
@Configuration
@EnableScheduling
public class SpringConfiguration {
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.newScheduledThreadPool(5);
}
...
当需要更多控制时,@Configuration
类可以实现调度配置器
您可以使用:
@Bean()
public ThreadPoolTaskScheduler taskScheduler(){
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(2);
return taskScheduler;
}
默认spring使用单个线程来调度任务。您可以使用@Configuration for类实现SchedulingConfigurer。参考:
https://crmepham.github.io/spring-boot-multi-thread-scheduling/
注释提供了关键信息以及解决方法:
默认情况下,将搜索关联的计划程序定义:
上下文中唯一的TaskScheduler bean或TaskScheduler
否则命名为“taskScheduler”的bean;同样的查找也将被删除
为ScheduledExecutorService bean执行如果两者都不是
是可解析的,则将使用本地单线程默认调度程序
在注册机构中创建和使用
当需要更多的控制时,可以实现@Configuration类
调度配置器。这就允许访问底层数据库
ScheduledTaskRegistrar实例。例如,下面的示例
演示如何自定义用于执行计划任务的执行器
任务:
(增加强调)2019年更新
您还可以在应用程序属性文件中设置一个属性来增加池大小:
spring.task.scheduling.pool.size=10
似乎从Spring Boot 2.1.0开始就存在了。使用XML文件添加到下面的行中
<task:scheduler id="taskScheduler" pool-size="15" />
<task:scheduled-tasks scheduler="taskScheduler" >
....
</task:scheduled-tasks>
....
请使用下面的链接作为参考。非常好的解释和实现:
).仅供参考:只提供普通文档的链接并说您有“配置”功能是没有帮助的。。。提供一个例子是非常有帮助的。我投了g。下面是德梅基的答案,而不是你的答案,正是因为这个原因。。。获取标题的提示引用的文档引用了
task:scheduler
,它有一个pool size
参数。这是否适用于没有池相关参数的@Scheduled
注释?@DavidSoroko我相信是这样。由于Executor
接口没有shutdown()
方法,我想最好使用ExecutorService
作为返回类型,以使bean定义正确。或者Spring会在运行时发现实际的bean类型吗?XML配置-
参见SchedulingConfigurerDoes不能与Spring自动配置一起工作的示例:无法注册在类路径资源[org/springframework/boot/autoconfigure/task/TaskSchedulingAutoConfiguration.class]中定义的bean“taskScheduler”。具有该名称的bean已经在类路径资源中定义了…链接到Spring文档?@DavidSoroko这在Javadoc中并不明显。在源代码中更容易看到它<代码>@Scheduled(和@EnableScheduling
)通过注册ScheduledAndNotationBeanPostProcessor
来处理。这个后置处理器使用了一个ScheduledTaskRegistrar
。我觉得你太客气了——它根本不在文档中。至于源代码,它可以在不同版本之间进行更改。我认为调用taskScheduler.initialize()在返回任务调度器的实例之前,如果spring boot version>=2.0,这是唯一的方法。重写taskScheduler()是无用的
<task:scheduler id="taskScheduler" pool-size="15" />
<task:scheduled-tasks scheduler="taskScheduler" >
....
</task:scheduled-tasks>