日期/时间呼叫方法



我正在寻找在给定日期/时间执行给定方法的现代(尤其是ZonedDateTime)。

我知道Timer类和 Quartz 库,如下所示(线程包括完整解决方案):

  • java-在特定日期[封闭]
  • 执行方法
  • 在Java中固定时间调用方法

但是这些线程很旧,从那以后就不使用新的Java功能和库元素。特别是,携带任何类型的Future对象非常方便,因为它们提供了一种简单的机制来取消它们。

因此,请不要建议涉及Timer Quartz 的解决方案。另外,我想拥有一个 vanilla 解决方案,而不是使用任何外部库。但请随时为Q& a。

提出建议。

ScheduledExecutorService

您可以使用ScheduledExecutorService(文档)类,该类可从Java 5开始使用,它将产生ScheduledFuture(文档),该类别可用于监视执行并取消执行。

特别是该方法:

ScheduledFuture<?> schedule​(Runnable command, long delay, TimeUnit unit)

哪个

提交了一个单枪任务,该任务在给定延迟后启用。

但是,您也可以根据实际用例(scheduleAtFixedRate和接受Callable而不是Runnable)的版本来研究其他方法。

由于Java 8(流,Lambdas,...),由于旧TimeUnit和较新的ChronoUnit(用于ZonedDateTime)之间的简易转换方法,因此此类变得更加方便,并且能够提供Runnable command作为lambda或方法参考(因为它是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);
}

注释

您可以在Temporal的方法中交换ZonedDateTime参数,然后接受其他日期/时间格式。

完成后,不要忘记关闭ScheduledExecutorService。否则,即使您的主程序已经完成,您也会运行一个线程。

scheduler.shutdown();

请注意,我们使用Instant而不是ZonedDateTime,因为只要正确计算时间差,区域信息与我们无关。Instant始终代表UTC中的时间,没有任何怪异现象(如 dst )。(尽管对于此应用程序并不重要,但它只是更干净)。

最新更新