我写了一个简单的概念验证,用于调度一个runnable在给定的时间执行.代码完全按照预期工作,并在计划的时间执行runnable:
public static void main(String[] args) throws InterruptedException, ExecutionException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a");
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable task = new Runnable() {
public void run() {
System.out.println("Task Ran @ " + formatter.format(LocalDateTime.now()));
}
};
LocalDateTime now = LocalDateTime.now();
LocalDateTime runTime = ciel(ChronoUnit.MINUTES, now.plusMinutes(1));
Duration duration = Duration.between(now, runTime);
long initialDelay = duration.toMillis();
System.out.println("Schedule @ " + formatter.format(now));
System.out.println("Expected @ " + formatter.format(runTime));
scheduler.schedule(task, initialDelay, TimeUnit.MILLISECONDS);
scheduler.shutdown();
scheduler.awaitTermination(2, TimeUnit.MINUTES);
}
private static LocalDateTime ciel(TemporalUnit precision, LocalDateTime time) {
return time.truncatedTo(precision).plus(1, precision);
}
输出:
Schedule @ 12/18/2023 11:31:47 AM
Expected @ 12/18/2023 11:33:00 AM
Task Ran @ 12/18/2023 11:33:00 AM
但是,如果我在程序运行时将系统置于睡眠状态,然后继续唤醒它,那么runnable将在计划时间之外执行:
Schedule @ 12/18/2023 11:35:53 AM
Expected @ 12/18/2023 11:37:00 AM
Task Ran @ 12/18/2023 11:39:13 AM
假设操作系统在计划时间之前唤醒,我如何补偿这一点,以便Runnable仍然在预期的时间执行?