猿问

在日期/时间调用方法

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

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

但这些线程相当陈旧,从那时起就不再使用新的 Java 特性和库元素。特别是,获得任何类型的Future对象都非常方便,因为它们提供了一种简单的机制来取消它们。

所以请不要建议涉及TimerQuartz的解决方案。另外,我想要一个普通的解决方案,不使用任何外部库。但是,为了问答,也可以随意提出这些建议。


慕田峪9158850
浏览 85回答 1
1回答

眼眸繁星

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 desiredScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();public static ScheduledFuture<?> scheduleFor(Runnable runnable, ZonedDateTime when) {&nbsp; &nbsp; Instant now = Instant.now();&nbsp; &nbsp; // Use a different resolution if desired&nbsp; &nbsp; long secondsUntil = ChronoUnit.SECONDS.between(now, when.toInstant());&nbsp; &nbsp; return scheduler.schedule(runnable, secondsUntil, TimeUnit.of(ChronoUnit.SECONDS));}调用很简单:ZonedDateTime when = ...ScheduledFuture<?> job = scheduleFor(YourClass::yourMethod, when);然后,您可以使用job来监视执行并在需要时取消它。例子:if (!job.isCancelled()) {&nbsp; &nbsp; job.cancel(false);}笔记ZonedDateTime您可以将方法中的参数交换为Temporal,然后它还接受其他日期/时间格式。完成后不要忘记关闭ScheduledExecutorService。否则,即使您的主程序已经完成,您也会有一个线程正在运行。scheduler.shutdown();请注意,我们使用Instant而不是ZonedDateTime,因为区域信息与我们无关,只要正确计算时间差即可。Instant始终代表 UTC 时间,没有像DST这样的奇怪现象。(虽然对于这个应用程序来说并不重要,但它更干净)。
随时随地看视频慕课网APP

相关分类

Java
我要回答