首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >完全独立于系统时间变化的Java调度器

完全独立于系统时间变化的Java调度器
EN

Stack Overflow用户
提问于 2012-01-28 18:05:35
回答 2查看 8.8K关注 0票数 17

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

在我的目标中使用64位的jre 1.6.0_26。

更新: ScheduledExecutorService在Windows上运行良好。问题只出现在运行64位JVM的基于64位Linux的系统上。它在运行32位JVM...strange的64位linux上运行良好。在任何博客上也没有找到任何相同的引用。

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

我已经向JDK 提交了缺陷,它被接受了,但已经被关闭并标记为 的副本。请投赞成票,如果你觉得值得修复它的话…我不知道为什么它没有得到修复,因为几年多来

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

代码语言:javascript
复制
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);
    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-01 13:46:03

在系统时间向后更改期间,有用于整体调度的bug in JVM,这也影响了非常基本的Object.wait和Thread.sleep方法。当系统时间切换回某些秒数时,让Java应用程序继续运行就变得太冒险了。你永远不会知道你的Java应用最终会变成什么样子。

因此,我们决定:

  • 编写看门狗脚本(非Java:)以检查时间更改。
  • 如果时间切换回一定数量,则关闭并重新启动Java应用程序。

另一种可能是迁移到32位JVM,但我们使用的是JNI,因此目标平台上使用的本地库不是32位兼容的。根据我们的经验,32位JVM将我们的目标限制在1.6G堆,这对我们来说根本不够。

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

编辑:除了上面的解决方案外,我们还在考虑克里斯的第一个建议:

  • 将NTP配置为永远不会有大的时间跳跃。只是慢慢地消磨时间。仅在停机期间手动应用大时间跳转。
票数 7
EN

Stack Overflow用户

发布于 2012-01-28 21:46:39

我解决了同样的问题,但没有找到解决方案。我研究了Quartz和所有内置的JRE方法。nanotime方法可能使用每个CPU的单调时钟,但我相信,如果将线程迁移到另一个CPU上,您可能会面临巨大的跳跃风险。我的结论如下:

  1. 将NTP配置为永远不会有大的时间跳跃。只是慢慢地消磨时间。仅在停机期间手动应用大时间跳转。
  2. 使用多个较短的超时,并且需要两个超时才能宣布远程计算机已死。如果您只有一个系统计时本身,这将不会有帮助,但可以帮助多个系统
  3. 故意使用远程计算机发送定期唤醒。如果你自己的时钟在两次唤醒之间倒退,那么你知道你所有的计时器都会延迟触发。

基本上,这是一个巨大的痛苦,但没有银弹。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9044423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档