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

时间:2018-10-19 08:17:55

标签: java spring concurrency cron scheduled-tasks

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

假设我有两个不同的cron作业,例如:

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

@Scheduled(cron= "0 * * * * *")
private void logHello() {
   log("hello!");
}

我有一个可以运行几天的功能,该功能每隔30分钟触发一次。 (0 30 * * * *)我们将其命名为sleepForDays()

我还有另一个功能,该功能应该每分钟记录一次问候。让我们将其命名为logHello()

问题:

  1. sleepForDays()一旦启动,我相信第二个sleepForDays()将在第一个sleepForDays()完成之前开始。对吧?

  2. logHello()一旦启动,sleepForDays()不会每分钟工作。我确实在生产环境中记录了此函数的内容,但是在输出文件中看不到那些日志。显然,sleepForDays()执行期间它不起作用。

意图:

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

  2. 我也想避免重复执行同一cronJob。如果sleepForDays()已经在执行,我不想再启动第二个TaskScheduler

我发布此问题的主要目的是问题2。关于StackOverflow中的类似帖子,我认为问题1的答案是肯定的。我想确保我在问题1中的假设是正确的。

谢谢您的时间!

编辑:

问题可能与以下事实有关:我使用默认参数初始化了TaskScheduler bean。默认情况下,@Bean public static TaskScheduler taskScheduler() { return new ConcurrentTaskScheduler(); } 不支持计划的cronjobs多线程。如果我使用多线程支持初始化TaskScheduled bean,我的问题1的答案是否仍然是?

Bean初始化如下:

TaskScheduler

编辑2:解决方案

非常感谢贡献者,我设法使用下面的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; } bean:

import xml.etree.ElementTree as ET
import re
import sys

with open(sys.argv[1]) as f:
    root = ET.fromstring(f.read())
    xmlns = ''
    m = re.search('{.*}', root.tag)
    if m:
        xmlns = m.group(0)
    print(root.find(xmlns + 'the_tag_you_want').text)

1 个答案:

答案 0 :(得分:3)

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

@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
    ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
    threadPoolTaskScheduler.setPoolSize(5);
    threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
    return threadPoolTaskScheduler;
}