如何安排不受计算机挂起影响的定时事件

时间:2014-11-08 10:57:55

标签: java timer delayed-execution

我想安排在特定时间发生的事件,无论计算机是否暂停。如果计算机在事件发生时被暂停,我希望在恢复时立即安排它。

我尝试了两种方法:一个带sleep()的线程和一个Swing Timer。这两种方法都依赖于定时延迟,并且两者都遇到同样的问题,即延迟倒计时在计算机暂停时暂停,并且仅在计算机恢复时继续,因此事件发生在(原始延迟+时间暂停)。

然后我猜到我应该做的是使用带有目标日期的(util)Timer,因为它指定了一个时间点,如下所示:

Date targetDate = new Date(System.currentTimeMillis() + (60 * 1000)); // in 1 min
Timer eventTimer = new Timer();
eventTimer.schedule(eventThread, targetDate);

不幸的是,这种情况完全相同。

我还查看了ScheduledExecutorService(虽然我认为这个应用程序有点过分),但它明确地使用了延迟,所以我认为它会遇到同样的问题。

我想做的是什么?

2 个答案:

答案 0 :(得分:1)

  

延迟倒计时暂停

不,这不是真正发生的事情。否则就意味着恢复时系统时间会出错!

  

我想做的是什么?

这是一个解决方案:

  • 让一个任务处理所有的调度,例如,每秒运行一次;
  • 在要执行的任务中,记录时间,使任务的类与预期的执行时间相比较;
  • 将所有这些任务放在PriorityQueue(甚至是PriorityBlockingQueue)中;
  • 当调度任务醒来时,查看任务;如果预期执行时间小于或等于当前时间,则将其出列并执行;重复,直到被查看的任务的预期执行时间大于当前时间

这不会使"立即执行恢复",但接近。

答案 1 :(得分:0)

事情甚至更奇怪。我有一个程序,每小时刷新一次数据,使用java.util.Timer和一个合适的TimerTask。使用openSuse到版本13.1,该程序按需运行 - 当由于暂停实时超过循环时,任务被立即调用""简历之后。 使用相同的jvm(1.8.0_40-b10)和相同的Linux内核(3.14.24)运行相同的程序,但使用openSuse 13.2时,任务不会在恢复时调用,而是仅在唤醒模式中的时间段过期后调用。 如果当前时间超过预定时间并在必要时重新同步任务,我通过功能键调用任务来解决此问题。这是令人讨厌的但是可以接受,因为简历无论如何都是通过击键来完成的。