[英]Is it possible to schedule a job with Spring @Scheduled annotation to run every hour but each time at random hour?
I would like to run my task/method each hour.. but each time at random minute. 我想每个小时运行我的任务/方法。但是每次都在随机时间运行。 I've already tried Spring @Scheduled to be started every day at a random minute between 4:00AM and 4:30AM but this solution is setting random initial value but after that same minute is used.
我已经尝试过将Spring @Scheduled每天在4:00 AM到4:30 AM之间的任意分钟启动,但是此解决方案设置了随机初始值,但是使用了同一分钟。
I would like to achieve a situation where the job is running like this. 我想实现一种工作正在这样运行的情况。 ex:
例如:
8:10 9:41 10:12 ... 8:10 9:41 10:12 ...
Right, so...this isn't a schedule. 对,所以...这不是时间表。 This is a non-deterministic event.
这是非确定性事件。
A scheduled event is something which is repeatable and something which can be consistently fired at a specific time. 预定事件是可重复的,并且可以在特定时间一致触发。 There's an order and predictability which go hand-in-hand with this.
有一个顺序和可预测性与此紧密相关。
By having a job fire off at a given hour but not necessarily at a given minute, you lose predictability which is what the @Scheduled
annotation would enforce (not necessarily through implementation, but as a side-effect; annotations may only contain compile-time constants and cannot dynamically change during runtime). 通过在给定的时间(但不一定在给定的分钟)解雇工作,您将失去可预测性,这是
@Scheduled
注释将强制执行的(不一定是通过实现,而是副作用;注释可能仅包含编译时)常量,并且无法在运行时动态更改)。
As for a solution, Thread.sleep
is brittle and will cause your entire application to sleep for that period of time which isn't what you want to do. 作为解决方案,
Thread.sleep
很脆弱,将导致整个应用程序在这段时间内进入睡眠状态,这不是您想要的。 Instead, you could wrap your critical code in a non-blocking thread and schedule that instead. 相反, 您可以将关键代码包装在一个非阻塞线程中,并进行调度。
Warning: Untested code below 警告:下面未经测试的代码
@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);
}
I leave the effort of managing resources in a thread-safe manner as an exercise for the reader. 我将以线程安全的方式管理资源的工作留给了读者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.