完全独立于系统时间变化的Java调度程序 [英] Java scheduler which is completely independent of system time changes

查看:35
本文介绍了完全独立于系统时间变化的Java调度程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Java Timer,然后切换到ScheduledExecutorService,但我的问题没有解决.因为在系统时间更改(通过 ntpd)之前安排的任务不会在指定的延迟时间执行.没有日志,因为什么都没有发生:(.

Was using Java Timer, Then switched to ScheduledExecutorService, but my problem is not fixed. As Tasks scheduled before system time change (through ntpd) are not executed on delay specified. Have no logs for same as nothing happens :(.

在 64 位 linux 上的目标中使用 jre 1.6.0_26 64 位.

using jre 1.6.0_26 64 bit in my target on 64 bit linux.

更新: ScheduledExecutorService 在 Windows 上运行良好.问题仅出现在运行 64 位 JVM 的基于 64 位 Linux 的系统上.它工作正常在64 位 linux 运行 32 位 JVM ......奇怪.也没有在任何博客上找到任何相同的参考.

Update: ScheduledExecutorService works fine on Windows. Problem is only on 64 bit Linux based system running 64 bit JVM. It works fine on 64 bit linux running 32 bit JVM...strange. Have not found any reference of same on any blogs either.

IBM 的 JAVA SDK 也有同样的问题(ibm-java-sdk-7.0-0.0-x86_64-archive.bin).

IBM's JAVA SDK has same problem (ibm-java-sdk-7.0-0.0-x86_64-archive.bin).

我已经提交了针对 JDK 7139684的缺陷,它被接受了,但已经被接受关闭和6900441 的标记重复.请投票给它,如果你觉得修复它是值得的......我不知道为什么它在几年多以来没有被修复

I had filed defect against JDK 7139684,It was accepted but has been closed and marked duplicate of 6900441. Please vote for it , if you feel its worth to get it fixed... I have no idea why its not been fixed since more than couple of years

这是我用来测试这个问题的示例代码:

Here is sample code I used to test this issue:

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);
    }

}

推荐答案

JVM 中的 bug 在 Sytem 时间期间的整体调度向后更改,这也影响了非常基本的 Object.wait &Thread.sleep 方法.当系统时间切换甚至几秒钟时,保持 Java App 运行变得太冒险了.你永远不知道你的 Java 应用程序最终会变成什么.

There is bug in JVM for overall scheduling during Sytem time changes backward, which also impacts very basic Object.wait & Thread.sleep methods. It becomes too risky to keep Java App running when system time switches back by even certain seconds. You never know what your Java App will end up to.

所以我们决定:

  • 编写看门狗脚本(非 Java :))来检查时间变化.
  • 如果时间倒退一定数量,请关闭并重新启动 Java 应用程序.

另一种可能性是迁移到 32 位 JVM,但我们使用的是 JNI,然后目标平台上使用的本机库与 32 位不兼容.同样根据我们的经验,32 位 JVM 将我们的目标限制为 1.6G 堆,这对我们来说根本不够.

Another possibility was to move to 32bit JVM, But we are using JNI and then native libraries used on target platform are not 32bit compatible. Also from our experience 32bit JVM limits our target to 1.6G heap, which is not at all sufficient for us.

我知道我们的解决方案不是最优雅的解决方案,但在 JVM 修复或找到更好的解决方案之前,似乎没有其他方法.

I know ours is not most elegant solution, but untill JVM is fixed or some better solution is found, there doesn't seem to be any other way.

除了上述解决方案外,我们还在考虑 Chris 的第一个建议:

Edited: We are also considering 1st suggestion from Chris in addition to above solution:

  • 将 NTP 配置为永远不会有大的时间跳跃.只消磨时间慢慢地.仅在停机期间手动应用大时间跳跃.

这篇关于完全独立于系统时间变化的Java调度程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆