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這樣的奇怪現象。(雖然對于這個應用程序來說并不重要,但它更干凈)。
添加回答
舉報