Java Spring:如何同时运行两个不同的cronjobs?

Ali*_*maz 2 java concurrency cron spring scheduled-tasks

首先,很抱歉,如果以前有人问过这个问题,我找不到类似的问题,所以我决定自己问。

假设我有两个不同的 cron 作业,如下所示:

@Scheduled(cron = "0 30 * * * *")
private void sleepForDays() {
    while(true) sleep();
}

@Scheduled(cron= "0 * * * * *")
private void logHello() {
   log("hello!");
}
Run Code Online (Sandbox Code Playgroud)

我有一个运行数天的函数,每 30 分钟触发一次。(0 30 * * * *) 让我们命名它sleepForDays()

我有另一个函数应该每分钟记录 hello 。让我们命名它logHello()

问题:

  1. 一旦sleepForDays()开始,我相信sleepForDays()在第一个完成之前第二个不会开始。正确的?

  2. 一旦sleepForDays()启动,logHello()并不是每分钟都在工作。我在生产环境中记录了此函数,但在输出文件中看不到这些日志。sleepForDays()显然它在执行时不起作用。

意向:

  1. 我希望不同的 cronJobs 彼此独立运行。换句话说,我不想sleepForDays()阻止logHello()

  2. 我还想避免重复执行相同的 cronJob。如果sleepForDays()已经执行,我不想再sleepForDays()启动。

我发布这个问题的主要观点是问题#2。关于 StackOverflow 中的类似帖子,我相信问题 1 的答案是肯定的。我想确保我在问题#1 中的假设是正确的。

感谢您的时间!

编辑:

问题可能是关于我使用默认参数初始化 bean 的事实TaskScheduler。默认情况下,TaskScheduler不支持计划的 cronjobs 的多线程。如果我使用多线程支持初始化 TaskScheduled bean,我的问题#1 的答案仍然是“是”吗?

Bean初始化如下:

@Bean
public static TaskScheduler taskScheduler() {
    return new ConcurrentTaskScheduler();
}
Run Code Online (Sandbox Code Playgroud)

编辑2:解决方案

非常感谢贡献者,我成功地使用下面的 bean 初始化同时运行这些函数。我只是TaskScheduler用这个替换了 bean:

@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(2);
    threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler"); // i dont know what it does, i used it anyways lol
    return threadPoolTaskScheduler;
}
Run Code Online (Sandbox Code Playgroud)

小智 5

默认情况下,所有 @Scheduled 方法共享一个线程。您可以通过定义自定义ThreadPoolTask​​Scheduler bean 来修改此行为:

@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(5);
    threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
    return threadPoolTaskScheduler;
}
Run Code Online (Sandbox Code Playgroud)