Java spring @Scheduled 注释方法是否在不同线程上运行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21993464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does spring @Scheduled annotated methods runs on different threads?
提问by froi
I have several methods annotated with @Scheduled(fixedDelay=10000)
.
我有几个方法用@Scheduled(fixedDelay=10000)
.
In the application context, I have this annotation-driven setup:
在应用程序上下文中,我有这个注释驱动的设置:
<task:annotation-driven />
The problem is, sometimes some of the method executions get delayed by seconds and even minutes.
问题是,有时某些方法的执行会延迟几秒甚至几分钟。
I'm assuming that even if a method takes a while to finish executing, the other methods would still execute. So I don't understand the delay.
我假设即使一个方法需要一段时间才能完成执行,其他方法仍然会执行。所以我不明白延迟。
Is there a way to maybe lessen or even remove the delay?
有没有办法减少甚至消除延迟?
采纳答案by G. Demecki
For completeness, code below shows the simplest possible way to configure scheduler with java config:
为了完整起见,下面的代码显示了使用 java config 配置调度程序的最简单方法:
@Configuration
@EnableScheduling
public class SpringConfiguration {
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.newScheduledThreadPool(5);
}
...
When more control is desired, a @Configuration
class may implement SchedulingConfigurer
.
当需要更多控制时,一个@Configuration
类可以实现SchedulingConfigurer
.
回答by Sotirios Delimanolis
A method annotated with @Scheduled
is meant to be run separately, on a different thread at a moment in time.
带有注释的方法@Scheduled
意味着在某个时刻在不同的线程上单独运行。
If you haven't provided a TaskScheduler
in your configuration, Spring will use
如果您没有TaskScheduler
在配置中提供 a ,Spring 将使用
Executors.newSingleThreadScheduledExecutor();
which returns an ScheduledExecutorService
that runs on a single thread. As such, if you have multiple @Scheduled
methods, although they are scheduled, they each need to wait for the thread to complete executing the previous task. You might keep getting bigger and bigger delays as the the queue fills up faster than it empties out.
它返回ScheduledExecutorService
在单个线程上运行的 。因此,如果您有多个@Scheduled
方法,尽管它们已被调度,但它们每个都需要等待线程完成执行前一个任务。随着队列填满的速度比排空的速度快,您可能会越来越大的延迟。
Make sure you configure your scheduling environment with an appropriate amount of threads.
确保使用适当数量的线程配置调度环境。
回答by JB Nizet
The documentation about schedulingsays:
If you do not provide a pool-size attribute, the default thread pool will only have a single thread.
如果不提供 pool-size 属性,则默认线程池将只有一个线程。
So if you have many scheduled tasks, you should configure the scheduler, as explained in the documentation, to have a pool with more threads, to make sure one long task doesn't delay all the other ones.
因此,如果您有许多计划任务,您应该按照文档中的说明配置调度程序,以拥有一个包含更多线程的池,以确保一个长任务不会延迟所有其他任务。
回答by sj8515465
you can use:
您可以使用:
@Bean()
public ThreadPoolTaskScheduler taskScheduler(){
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(2);
return taskScheduler;
}
回答by zhaoyou
default spring using a single thread for schedule task. you can using @Configuration for class implements SchedulingConfigurer . referce: https://crmepham.github.io/spring-boot-multi-thread-scheduling/
默认 spring 使用单个线程进行调度任务。您可以将 @Configuration 用于类实现 SchedulingConfigurer 。参考:https://crmepham.github.io/spring-boot-multi-thread-scheduling/
回答by jgreen
The @EnableSchedulingannotation provides the key information and how to resolve it:
该@EnableScheduling注释提供了关键信息,以及如何解决它:
By default, will be searching for an associated scheduler definition: either a unique TaskScheduler bean in the context, or a TaskScheduler bean named "taskScheduler" otherwise; the same lookup will also be performed for a ScheduledExecutorService bean. If neither of the two is resolvable, a local single-threaded default scheduler will be created and used within the registrar.
When more control is desired, a @Configuration class may implement SchedulingConfigurer. This allows access to the underlying ScheduledTaskRegistrar instance. For example, the following example demonstrates how to customize the Executor used to execute scheduled tasks:
默认情况下,将搜索关联的调度程序定义:上下文中唯一的 TaskScheduler bean,或者否则名为“taskScheduler”的 TaskScheduler bean;还将对 ScheduledExecutorService bean 执行相同的查找。如果两者都不可解析,则会在注册器中创建和使用本地单线程默认调度程序。
当需要更多控制时,@Configuration 类可以实现 SchedulingConfigurer。这允许访问底层 ScheduledTaskRegistrar 实例。例如,以下示例演示如何自定义用于执行计划任务的 Executor:
@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);
}
}
(emphasis added)
(强调)
回答by L.Butz
UPDATE 2019
2019 年更新
There is also a property you can set in your application properties file that increases the pool size:
您还可以在应用程序属性文件中设置一个增加池大小的属性:
spring.task.scheduling.pool.size=10
spring.task.scheduling.pool.size=10
Seems to be there since Spring Boot 2.1.0.
似乎自 Spring Boot 2.1.0 以来就存在。