当计算机在休眠后唤醒时计划任务运行数千次
Scheduled task runs thousands of times when computer wakes after sleeping
使用 Spring 的 @Scheduled
注释方法并指定固定延迟,如下所示:
@Scheduled(fixedRate = 5000)
public void test() {
log.info("The time is {}", Instant.now());
}
当我在休眠后唤醒计算机时,任务是 运行 很多次一个接一个。
The time is 2020-07-14T08:00:30.358073400Z
The time is 2020-07-14T08:00:35.358969600Z
The time is 2020-07-14T08:00:40.358066100Z
...
The time is 2020-07-14T08:02:51.806689500Z
The time is 2020-07-14T08:02:51.806689500Z
The time is 2020-07-14T08:02:51.806689500Z
The time is 2020-07-14T08:02:51.806689500Z
The time is 2020-07-14T08:02:51.806689500Z
The time is 2020-07-14T08:02:51.807651500Z
The time is 2020-07-14T08:02:51.807651500Z
...
如何让电脑唤醒时只运行一次?
您可以使用 AtomicBoolean
标志,表明该任务已经 运行:
private final AtomicBoolean running = new AtomicBoolean(false);
然后在你预定的方法中
if (running.compareAndSet(false, true)) {
log.info("The time is {}", Instant.now());
running.set(false);
}
来自 compareAndSet(expect, update)
的 javadoc:
Atomically sets the value to the given updated value if the current value == the expected value.
Returns: true
if successful. False
return indicates that the actual value was not equal to the expected value.
因此,if
将检查当前没有任务 运行,然后才会执行您的代码。
使用:@Scheduled(cron = "*/5 * * * * *")
.
使用 cron 表达式时,错过的执行不会排队。
此外,就像@Lino 注意到的那样,您指定了 fixedRate
而不是 fixedDelay
。将 fixedRate
更改为 fixedDelay
也可以解决您的问题,但请考虑到行为可能会发生变化,因为 fixedDelay
是上次调用结束之间的固定时间段 和下一个 的开始,而 fixedRate
是一个以毫秒为单位的固定周期 调用之间 .
使用 Spring 的 @Scheduled
注释方法并指定固定延迟,如下所示:
@Scheduled(fixedRate = 5000)
public void test() {
log.info("The time is {}", Instant.now());
}
当我在休眠后唤醒计算机时,任务是 运行 很多次一个接一个。
The time is 2020-07-14T08:00:30.358073400Z
The time is 2020-07-14T08:00:35.358969600Z
The time is 2020-07-14T08:00:40.358066100Z
...
The time is 2020-07-14T08:02:51.806689500Z
The time is 2020-07-14T08:02:51.806689500Z
The time is 2020-07-14T08:02:51.806689500Z
The time is 2020-07-14T08:02:51.806689500Z
The time is 2020-07-14T08:02:51.806689500Z
The time is 2020-07-14T08:02:51.807651500Z
The time is 2020-07-14T08:02:51.807651500Z
...
如何让电脑唤醒时只运行一次?
您可以使用 AtomicBoolean
标志,表明该任务已经 运行:
private final AtomicBoolean running = new AtomicBoolean(false);
然后在你预定的方法中
if (running.compareAndSet(false, true)) {
log.info("The time is {}", Instant.now());
running.set(false);
}
来自 compareAndSet(expect, update)
的 javadoc:
Atomically sets the value to the given updated value if the current value == the expected value.
Returns:
true
if successful.False
return indicates that the actual value was not equal to the expected value.
因此,if
将检查当前没有任务 运行,然后才会执行您的代码。
使用:@Scheduled(cron = "*/5 * * * * *")
.
使用 cron 表达式时,错过的执行不会排队。
此外,就像@Lino 注意到的那样,您指定了 fixedRate
而不是 fixedDelay
。将 fixedRate
更改为 fixedDelay
也可以解决您的问题,但请考虑到行为可能会发生变化,因为 fixedDelay
是上次调用结束之间的固定时间段 和下一个 的开始,而 fixedRate
是一个以毫秒为单位的固定周期 调用之间 .