1 回答
TA贡献1873条经验 获得超9个赞
ScheduledExecutorService
您可以使用自 Java 5 起可用的ScheduledExecutorService( documentation ) 类。它将产生一个ScheduledFuture( documentation ),可用于监视执行并取消它。
具体来说,方法:
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
哪个
提交在给定延迟后启用的一次性任务。
但是您也可以查看其他方法,具体取决于实际用例(scheduleAtFixedRate以及接受Callable而不是 的版本Runnable)。
由于 Java 8 (Streams, Lambdas, ...) 这个类变得更加方便,因为TimeUnit新旧ChronoUnit(对于你的ZonedDateTime)之间的简单转换方法的可用性,以及提供Runnable commandas lambda 或方法的能力参考(因为它是 a FunctionalInterface)。
例子
让我们看一个执行您要求的示例:
// Somewhere before the method, as field for example
// Use other pool sizes if desired
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
public static ScheduledFuture<?> scheduleFor(Runnable runnable, ZonedDateTime when) {
Instant now = Instant.now();
// Use a different resolution if desired
long secondsUntil = ChronoUnit.SECONDS.between(now, when.toInstant());
return scheduler.schedule(runnable, secondsUntil, TimeUnit.of(ChronoUnit.SECONDS));
}
调用很简单:
ZonedDateTime when = ...
ScheduledFuture<?> job = scheduleFor(YourClass::yourMethod, when);
然后,您可以使用job来监视执行并在需要时取消它。例子:
if (!job.isCancelled()) {
job.cancel(false);
}
笔记
ZonedDateTime您可以将方法中的参数交换为Temporal,然后它还接受其他日期/时间格式。
完成后不要忘记关闭ScheduledExecutorService。否则,即使您的主程序已经完成,您也会有一个线程正在运行。
scheduler.shutdown();
请注意,我们使用Instant而不是ZonedDateTime,因为区域信息与我们无关,只要正确计算时间差即可。Instant始终代表 UTC 时间,没有像DST这样的奇怪现象。(虽然对于这个应用程序来说并不重要,但它更干净)。
添加回答
举报