【问题标题】:How to schedule a task in Java Swing application?如何在 Java Swing 应用程序中安排任务?
【发布时间】:2015-07-27 14:15:49
【问题描述】:

我有一个要求,我需要复制我的一些文件并将其放到内部服务器上。这需要定期发生,例如每天晚上 8 点。这也是一个 Swing 应用程序,在我的本地 PC 上运行。我知道我可以使用 Java 来安排任务,可以使用 java.util.TimeJodaTime 甚至更好的 Quartz Scheduler

但是,问题来了。没有人会为了这个调度程序让计算机保持 24 小时开机。据我所知,如果有人重新启动 PC,Java 调度程序也会死掉。相反,一旦计划了任务,如果计算机打开,计划的任务应该在每天晚上 8 点发生,无需人工干预。这意味着,无需重新启动应用程序并重新调度。

我描述的这个功能很常见,可以在所有的病毒防护、基于窗口的警报等中看到。但是我如何在 Java 中实现相同的功能?目前,如果我必须使用特定于 Windows 的解决方案,例如使用 JNI 或对批处理文件进行一些破解等(我正在使用 Windows),那也很好。

至少java可以做到这一点吗?

【问题讨论】:

  • 为什么不让应用程序在启动时运行?
  • @ThomasNairn:Quartz 调度程序在机器关闭时终止。我不知道 GUI 是如何发生这种情况的,但我在 Web 服务器中看到过这种情况。
  • 但如果应用程序在后台运行。 (setVisible(false);) 你可以重新安排时间,甚至只用一个简单的线程来监控时间?
  • 如果计算机在给定时间仍然停机怎么办?无论哪种方式,您都需要一个操作系统级别的工具(或者等效地,可以保留任务并在启动时启动的工具),例如 cron
  • @biziclop:如果电脑宕机了,没关系。没有副本。

标签: java swing time scheduled-tasks quartz-scheduler


【解决方案1】:

Answer by Nairn 是正确的。这是有关在重新启动 Java 应用程序后设置计划的编码的详细信息。

ScheduledExecutorService

如果使用ScheduledExecutorService 接口来安排您的重复任务,则其中一个参数是initialDelay。您指定等待任务第一次出现的时间量。在该一次延迟之后,您的任务计划在另一个参数period 指定的每个时间量后重新发生。

因此,每次重新启动后,您都会将当前时刻与第一次运行所需的时刻进行比较。两者之间的时间跨度是您指定为 initialDelay 参数的量。

首先获取当前时刻。

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

在同一天设置您想要(目标)的时间。

LocalTime target = LocalTime.of( 20 , 0 );
ZonedDateTime then = ZonedDateTime.of( now.toLocalDate() , target , z );

检查今天的那个时间是否已经过去。如果过去,则添加一天以到达后一天。

if ( ! then.isAfter( now ) ) {  // If already past our target of 8 PM today, move to tomorrow.
    then = then.plusDays( 1 );
}

计算从现在到我们想要运行第一次任务的未来时刻之间的时间跨度 (Duration)。

Duration initialDelay = Duration.between( now ; then );

指定我们希望以Duration 对象的形式运行此任务 (period) 的频率。

Duration period = Duration.ofHours( 24 );

将我们的一对Duration 对象转换为一些分钟数或秒数或毫秒数或您想要的任何粒度。请记住,您的任务并不是在您想要的那一瞬间完成的。您的任务可能会因线程执行调度等原因而延迟,或者因为您的任务的下一次运行正在等待上一次运行完成。所以我怀疑TimeUnit.SECONDS 甚至分钟对于日常任务来说是一个足够精细的粒度。

myScheduledExecutorService.scheduleAtFixedRate( 
    myRunnable , 
    initialDelay.getSeconds() , 
    period.getSeconds() , 
    TimeUnit.SECONDS 
) ; 

回顾一下:

  • initialDelay 是在您的应用重新启动后用于安排第一次运行任务的时间跨度。
  • period 是用于重复运行任务的时间跨度。

【讨论】:

    【解决方案2】:

    为了在重新启动后调度和保持应用程序调度(在 Java 中)是让 Java 应用程序重新启动并再次调度。

    让应用程序在启动时运行:Run Java application at Windows startup,然后重新调度。

    【讨论】:

      猜你喜欢
      • 2011-01-30
      • 2012-01-23
      • 2020-03-02
      • 2020-10-12
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多