是否可以将带有Spring @Scheduled批注的作业安排为每小时运行一次,但每次随机运行一次?

时间:2019-04-15 20:44:03

标签: java spring random schedule

我想每小时运行一次任务/方法,但是每次都随机运行一分钟。 我已经尝试过Spring @Scheduled to be started every day at a random minute between 4:00AM and 4:30AM,但是此解决方案正在设置随机初始值,但是使用了同一分钟。

我希望达到这样的状态,作业正在运行。例如:

8:10 9:41 10:12 ...

1 个答案:

答案 0 :(得分:2)

对,所以...这不是时间表。这是一个不确定事件。

预定的事件是可重复的,并且可以在特定时间持续触发。与此相关的是顺序和可预测性。

通过在给定的小时解雇工作,而不是在给定的分钟没必要,您将失去可预测性,而可预测性正是@Scheduled注释将要执行的(不一定通过实现,而是作为副作用;注释只能包含编译时常量,并且不能在运行时动态更改。

对于解决方案,Thread.sleep很脆弱,会导致您的整个应用程序在 不是 < / strong>您想做什么。相反,you could wrap your critical code in a non-blocking thread并安排它。

警告:下面未经测试的代码

@Scheduled(cron = "0 0 * * * ?")
public void executeStrangely() {
    // Based on the schedule above,
    // all schedule finalization should happen at minute 0.
    // If the pool tries to execute at minute 0, there *might* be
    // a race condition with the actual thread running this block.
    // We do *not* include minute 0 for this reason.
    Random random = new Random();
    final int actualMinuteOfExecution = 1 + random.nextInt(59);
    final ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);

    exec.schedule(() -> {
        // Critical code here
    }, actualMinuteOfExecution, TimeUnit.MINUTES);
}

我将以线程安全的方式管理资源的工作留给了读者。