检测java中的系统时间是否向后移动,或者是否使用了防时间计时器

检测java中的系统时间是否向后移动,或者是否使用了防时间计时器,java,timer,Java,Timer,我有一个使用ntp的盒子,我们有几个java程序在上面运行,显示一个时钟。我们面临的问题是,如果有任何事情使系统时间倒转,我们所有的计时器都会停止并等待,直到系统时间回到原来的位置。我需要找到一种方法来检测系统时间何时被向后更改,并重置所有计时器,或者找到一组可以重复调度但仍然可以防止时钟更改的计时器 值得注意的是,我已经尝试了quartz定时器包,它与常规java定时器有相同的问题。听起来时钟小部件好像坏了。UI小部件应该显示模型的当前状态,在本例中,模型是系统时间。当然,对于时钟,您需要计划

我有一个使用ntp的盒子,我们有几个java程序在上面运行,显示一个时钟。我们面临的问题是,如果有任何事情使系统时间倒转,我们所有的计时器都会停止并等待,直到系统时间回到原来的位置。我需要找到一种方法来检测系统时间何时被向后更改,并重置所有计时器,或者找到一组可以重复调度但仍然可以防止时钟更改的计时器


值得注意的是,我已经尝试了quartz定时器包,它与常规java定时器有相同的问题。

听起来时钟小部件好像坏了。UI小部件应该显示模型的当前状态,在本例中,模型是系统时间。当然,对于时钟,您需要计划每秒执行一次
repaint()
,但是当重新绘制时,它应该呈现系统时间,而不是试图跟踪时间本身

这一原则甚至适用于非UI组件。确定组件对计时错误的容差,并有一个后台线程以该间隔刷新组件。然而,在刷新期间,使用的是系统时间,而不是独立的内部时钟


更新:

基本的
ScheduledExecutorService
没有遇到这个问题,至少在我的平台上是这样

ScheduledExecutorService worker = Executors.newScheduledThreadPool(1);
worker.schedule(new Runnable() {
  public void run()
  {
    update();
  }
}, 100, TimeUnit.MILLISECONDS);

几乎所有的计时器都会设定未来时间,然后定期将当前时间与给定时间进行比较。这就是为什么当实时倒转时计时器会“暂停”的原因

不幸的是,JVM中的所有计时器都与一天中的时间相关。例如,java.util.Timer执行Object.wait(毫秒)操作,以触发事件。这可以归结为一个线程调用,它也会等待t毫秒。它总是相对于“一天中的时间”


因此,在java中,基本上没有真正的方法可以做到这一点,除非有一个旋转的、吸CPU的循环等待时间倒转,以便通知您关心的计时器重置。

时钟倒转了多远?ntp通常使用时钟转换来推动时钟的任意方向,不需要将其更改几秒钟。系统中存在一些错误,使时间倒退了3或4个小时。几乎就像我们有两个相互竞争的ntp服务器,它们无法达成一致。是的,这也是我想到的,但是我发现Thread.sleep()对系统时钟的变化免疫。所以我想我可以有一个线程休眠1秒,然后检查时间是否向后移动。问题不是widgit试图跟踪时间本身,它每秒调用一次new Date(),如果你将系统时间向后移动,那么实际更新/设置时钟动画的java计时器会暂停执行,直到系统恢复到以前的状态。@tharris-我明白了;我以前没有遇到过那个问题。然而,我使用的
ScheduledExecutorService
实现似乎不受问题的影响,并且有一个类似于
Timer
类的API(尽管它是更新的、更健壮的
java.util.concurrent
包的一部分)。请参阅我的更新以获取一个示例。@erickson:(这不适用于Ubuntu11.10 java 6 update 26。我现在也有同样的问题