Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java spring@Scheduled注释方法是否在不同的线程上运行?_Java_Spring_Scheduled Tasks - Fatal编程技术网

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>