在自己的线程中运行每个Spring Scheduler [英] Running each Spring Scheduler in its own thread
问题描述
我有多个带有@Scheduled
批注的组件,而且我发现即使一次调度它们同时运行,Spring一次也只能启动一个组件.
I have multiple components with @Scheduled
annotations, and I see that Spring only starts one at a time, even if they are scheduled to run on the same time.
我的用例如下.我希望每个@Scheduled注释都可以在其自己的线程中运行,但每个线程只能运行一次.
My use case is as follows. I want each @Scheduled annotation to run in its own thread, but only once for each thread.
使用两个调度程序提供此伪代码:
Given this pseudo code with two schedulers:
@Scheduled(cron = "0 * * * * *") //run every minute
public void methodA() {
log.info("Running method A");
executeLongRunningJob("Finished method A");
}
@Scheduled(cron = "0 * * * * *") //run every minute
public void methodB() {
log.info("Running method B");
executeLongRunningJob("Finished method B");
}
private void executeLongRunningJob(String msg) {
Thread.sleep(70 seconds);
System.out.println(msg);
}
请注意,该任务花费的时间比计划的调度程序要运行的时间更长.这很关键.我不希望调度程序在完成运行之前再次启动.
开箱即用地运行此代码将为我提供以下输出:
Running this code out of the box gives me this output:
Running method A
Finished method A
Running method B
Finished method B
Running method A
Finished method A
Running method B
Finished method B
... and so on
显然,它在单个线程中同时运行两个调度程序.
So obviously its running both schedulers in a single thread.
当我在昂贵的方法上放置@Async
时,几乎可以得到正确的行为,除了昂贵的方法在启动新的调度程序之前尚未完成.
When I put @Async
on my expensive method, then I almost get the correct behavior, except the expensive method is not finished before a new scheduler is started.
Running method A
Running method B
Running method A
Running method B
Finished method A
Finished method B
... and so on
我想要的是此输出:
What I would like is this output:
Running method A
Running method B
Finished method A
Finished method B
Running method A
Running method B
Finished method A
Finished method B
... and so on
我该怎么做? 我希望每个Scheduler能够同时运行,但是要等到它完成后才能再次运行. 请记住,我有两个以上的调度程序在相同的时间运行,有时甚至在不同的时间运行.
How can I accomplish this? I want each Scheduler to run concurrently, but wait until it is finished before allowed to run again. Remember I have more than two Schedulers running in same and sometimes different times.
推荐答案
您是对的-默认情况下,调度程序使用大小为1的线程池,因此将按顺序处理每个任务.您可以通过配置 TaskScheduler
具有所需池大小的bean.考虑以下示例:
You're right - by default scheduler uses a thread pool with size 1, so every task is being processed sequentially. You can it by configuring TaskScheduler
bean with desired pool size. Consider following example:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.Date;
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public TaskScheduler taskScheduler() {
final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10);
return scheduler;
}
@Scheduled(fixedDelay = 2 * 1000L, initialDelay = 3 * 1000L)
public void scheduled1() throws InterruptedException {
System.out.println(new Date() + " " + Thread.currentThread().getName() + ": scheduled1");
Thread.sleep(1000);
}
@Scheduled(fixedDelay = 3 * 1000L, initialDelay = 3 * 1000L)
public void scheduled2() throws InterruptedException {
System.out.println(new Date() + " " + Thread.currentThread().getName() + ": scheduled2");
Thread.sleep(1000);
}
}
它将在单独的线程中运行每个计划的任务,例如:
It will run every scheduled task in a separate thread, for example:
Tue Jul 18 20:21:50 CEST 2017 taskScheduler-1: scheduled2
Tue Jul 18 20:21:50 CEST 2017 taskScheduler-2: scheduled1
Tue Jul 18 20:21:53 CEST 2017 taskScheduler-1: scheduled1
Tue Jul 18 20:21:54 CEST 2017 taskScheduler-3: scheduled2
Tue Jul 18 20:21:56 CEST 2017 taskScheduler-2: scheduled1
Tue Jul 18 20:21:58 CEST 2017 taskScheduler-4: scheduled2
Tue Jul 18 20:21:59 CEST 2017 taskScheduler-1: scheduled1
这篇关于在自己的线程中运行每个Spring Scheduler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!