完全独立于系统时间变化的Java调度器
使用Java定时器,然后切换到ScheduledExecutorService,但我的问题没有解决。 因为在系统时间更改(通过ntpd)之前计划的任务不会在指定的延迟上执行。没有日志,因为没有发生任何事件:( 在64位linux上的我的目标中使用jre 1.6.02664位 更新:ScheduledExecutorService在Windows上运行正常。问题只出现在运行64位JVM的基于64位Linux的系统上。它运行正常 在…上 运行32位JVM的64位linux…奇怪。在任何博客上也没有找到相同的参考 IBM的JavaSDK也有同样的问题 (ibm-java-sdk-7.0-0.0-x86_64-archive.bin) 我已针对JDK提交了缺陷,该缺陷已被接受,但已被关闭并关闭 标记为的副本。如果您觉得合适,请投赞成票 修好它是值得的……我不知道为什么它几年来一直没有修好 以下是我用来测试此问题的示例代码:完全独立于系统时间变化的Java调度器,java,timer,32bit-64bit,scheduler,ntp,Java,Timer,32bit 64bit,Scheduler,Ntp,使用Java定时器,然后切换到ScheduledExecutorService,但我的问题没有解决。 因为在系统时间更改(通过ntpd)之前计划的任务不会在指定的延迟上执行。没有日志,因为没有发生任何事件:( 在64位linux上的我的目标中使用jre 1.6.02664位 更新:ScheduledExecutorService在Windows上运行正常。问题只出现在运行64位JVM的基于64位Linux的系统上。它运行正常 在…上 运行32位JVM的64位linux…奇怪。在任何博客上也没有找
package test;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author yogesh
*
*/
public class TimerCheck implements Runnable {
ScheduledExecutorService worker;
public TimerCheck(ScheduledExecutorService worker) {
super();
this.worker = worker;
this.worker.schedule(this, 1, TimeUnit.SECONDS);
}
private static void update() {
System.out.println("TimerCheck.update() "+new Date(System.currentTimeMillis()));
}
@Override
public void run() {
update();
worker.schedule(this, 1, TimeUnit.SECONDS);
}
/**
* @param args
*/
public static void main(String[] args) {
ScheduledExecutorService worker = Executors.newScheduledThreadPool(1);
new TimerCheck(worker);
}
}
我针对同一个问题进行了研究,但没有找到解决方案。我查看了Quartz和所有内置JRE方法。nanotime方法可能会使用每个CPU的单调时钟,但我相信,如果线程迁移到另一个CPU,则会有大的跳跃风险。我的结论如下:
- 编写看门狗脚本(非Java:)以检查时间更改
- 如果时间倒转一定量,请关闭并重新启动Java应用程序
- 将NTP配置为永远不会有大的时间跳跃。只是浪费时间 慢慢地。仅在停机期间手动应用大时间跳转
worker.schedule(这个,100000000,TimeUnit.nanoseconds);
与worker.schedule(这个,1,TimeUnit.SECONDS)相同;
@ChrisDolan谢谢。但我更关注的是日程安排问题。你能将系统设置为GMT吗?GMT没有夏令时。但你最终应用了这些解决方案吗。对我来说,这些是不可能的:)。@YoK,是的,三个都是。我的场景是检测主服务是否/何时死亡,以便备份可以自动接管。在我使用过的所有NTP配置中,行为都是:如果同步在N分钟内(比如2分钟),则以每分钟X毫秒的速率(比如20分钟)缓慢地将时钟旋转到正确的时间。如果同步时间超过N分钟,则NTP将发出系统日志消息警告错误并变为被动。有趣的。。。将要求我的NTP人员查看它。nanoTime
应在所有CPU中保持一致-请参阅@TomAnderson cool,谢谢更新。我的信息已经过时了。是否有任何计时器实现利用了这一点?接受这个答案作为解决方法:(。在等待适当的解决方案时。我不明白,它对JVM的影响有多大。从您的aswer来看,它似乎是一个关键错误。例如,如果我使用Object.wait(1),时钟向后移动——这是否意味着线程永远不会被唤醒?@BegemoT它并不意味着它永远不会被唤醒……但它会在(时钟向后移动+1)之后被唤醒。这是危险的。而且,它只会发生在64位linux上的64位JVM上。