【问题标题】:Java Quartz-scheduler between timeJava Quartz-时间之间的调度器
【发布时间】:2018-10-10 06:16:26
【问题描述】:

我有一份工作,我想在每天的特定时间(例如上午 8 点至上午 10 点,间隔 5 分钟)开始使用石英调度程序 (v2.1.5),不使用 cron 表达式,只使用本机方法。 (通过我理解的本地方法在该石英库中实现)。 我有触发器:

TriggerBuilder builder = TriggerBuilder.newTrigger()
                .withIdentity(name, group)
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInMilliseconds(interval)
                        .repeatForever());

当然,cron 表达式很困难,我可以使用它来代替。但无论如何,我只想知道是否可以在该问题中使用本机方法。乐于接受任何建议!

【问题讨论】:

    标签: java quartz-scheduler


    【解决方案1】:

    这是来自Quartz tutorial 的示例(稍作修改):

    var cal = new DailyCalendar(8, 0, 0, 0, 10, 0, 0, 0); // range start and end hours, minutes, seconds and millis
    cal.setInvertTimerange(true); // by default the date interval specified above is excluded from execution. 
    // This turns it around and only allows execution within the interval
    
    var t2 = TriggerBuilder.newTrigger()
        .withIdentity("myTrigger2")
        .forJob("myJob2")
        .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInMilliseconds(interval)
                        .repeatForever());
        .modifiedByCalendar(cal)
        .build();
    

    诀窍是有一个简单的触发器(如上所示),然后有一个日历实现,可以指定允许执行该触发器的时间。

    【讨论】:

    • 非常感谢您的回答!不幸的是,它没有解决我的问题。我想在上午 8 点到 10 点之间以一定的时间间隔(例如 5 秒)按计划运行作业,因此它比一个执行更多。我想每天重复一遍。
    • @Xavizo 我更新了答案 - 这应该适合你。
    • @MatthiasHuttar 看来 DailyCalendar 是我要找的。谢谢! :)
    【解决方案2】:

    API 方法涵盖了几个简单(每个 X,X 点)和不太简单(X 天 A、B、C 天,X 月每月)的场景,但您的方法有点超出这个范围。
    您可以尝试这样来安排每 5 分钟运行一次的作业,早上 8 点到 10 点:

    Trigger trigger = TriggerBuilder.newTrigger() // identity, job, etc.
            .withSchedule(simpleSchedule()
                    .withIntervalInMinutes(5)
                    .repeatForever())
            .startAt(DateBuilder.tomorrowAt(8,0,0))
            .endAt(DateBuilder.tomorrowAt(10,0,0))
            .build();
    

    然后在你的工作中加入一些逻辑,以便在完成后以同样的方式重新安排第二天的工作。
    或者,您可以将其安排为永远每 5 分钟运行一次,并在执行任何操作之前让作业检查它是否在上午 8 点到 10 点之间。

    或者你可以使用,你知道的...... cron 表达式:

    Trigger trigger = TriggerBuilder.newTrigger() // identity, job, etc.
            .withSchedule(cronSchedule("0 0/5 8-10 * * ? *"))
            .startAt(DateBuilder.evenMinuteDateAfterNow())
            .build();
    

    这正是你想要的——这就是 cron 表达式的用途。

    【讨论】:

    • Cron 表达式在您使用小时/天等时很有用,但当您想通过在分钟或秒之间触发来使用它时(例如,8:55 - 10:15 有一定间隔)它可能涉及问题(您无法为该问题提供正确的表达方式)。这就是为什么我会避免这种方式。感谢您的回答!
    • 是的,我知道 cron 表达式的局限性,但是对于您问题中更合理的示例,它们符合要求。那些对 cron “不可行”的其他时间表,我发现它们在生产中非常罕见,但如果你真的需要一个,你可以应用我的第一个解决方案(日内调度的简单时间表并让工作完成日常重新安排)。
    • 您的解决方案确实很有帮助,但是如果我想在我提供它的同一天执行工作怎么办?实际上,我必须等待一天才能进行日常执行。也许触发作业(使用方法 todayAt 而不是 tommorowAt)由另一个计划每 24 小时运行一次的作业(startAt 12am + 间隔 24h)?
    • 我使用了tomorrowAt,因为这是工作应该做的正确重新安排自己的事情。在我们的设置中,作业的初始调度是在应用程序启动期间完成的(RAMJobStore),这可能随时发生;如果我们使用todayAt(8,0,0) 并且应用程序在早上 8 点之后重新启动,那么作业将永远不会运行。使用tomorrowAt 确保它确实如此。但是,是的,如果你想让它在你安排它的同一天运行(你没有提到),是的,你可以使用todayAt(注意失火)。如果第一次运行的时间不重要,你也可以只 startNow()
    • 另外,也许我不清楚,但使用 tomorrowAt 重新安排将在您工作的 execute() 方法结束时,而第一个 scheduleJob() 将在您的不同部分代码(应用程序初始化代码、作业调度 UI 等)。恕我直言,无需单独的“调度程序作业”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多