【问题标题】:Is it possible to schedule a job with Spring @Scheduled annotation to run every hour but each time at random hour?是否可以使用 Spring @Scheduled 注释安排作业每小时运行一次,但每次随机运行一次?
【发布时间】:2019-04-16 06:42:53
【问题描述】:
【问题讨论】:
标签:
java
spring
random
schedule
【解决方案1】:
好的,所以...这不是时间表。这是一个不确定的事件。
预定事件是可重复的,并且可以在特定时间持续触发的事件。有一个顺序和可预测性与之齐头并进。
通过在给定时间触发作业而不是必须在给定分钟触发,您将失去@Scheduled 注释将强制执行的可预测性(不一定通过实现,而是作为副作用;注解只能包含编译时常量,不能在运行时动态更改)。
至于解决方案,Thread.sleep 很脆弱,会导致您的整个应用程序休眠一段时间,而 不是 你想做什么。相反,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);
}
我将以线程安全的方式管理资源的工作留给读者作为练习。