java getsystemtime_java – 为什么System.nanoTime()和System.currentTimeMillis()如此迅速地分开?...

为了进行诊断,我希望能够在长时间运行的服务器应用程序中检测系统时钟的变化。由于System.currentTimeMillis()基于挂钟时间,System.nanoTime()是基于独立(*)的挂钟时间的系统定时器,我以为可以使用这些值之间的差异来检测系统时间变化。

我写了一个快速测试应用程序,以查看这些值之间的差异是如何稳定的,令我惊讶的是,数值在几秒钟的时间内立刻对我而言是分歧的。几次我看到更快的分歧。这是在使用Java 6的Win7 64位桌面上。我没有在Linux(或Solaris或MacOS)下面尝试下面的测试程序来查看它是如何运行的。对于这个应用程序的一些运行,分歧是积极的,一些运行它是负面的。它似乎取决于桌面正在做什么,但很难说。

public class TimeTest {

private static final int ONE_MILLION = 1000000;

private static final int HALF_MILLION = 499999;

public static void main(String[] args) {

long start = System.nanoTime();

long base = System.currentTimeMillis() - (start / ONE_MILLION);

while (true) {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// Don't care if we're interrupted

}

long now = System.nanoTime();

long drift = System.currentTimeMillis() - (now / ONE_MILLION) - base;

long interval = (now - start + HALF_MILLION) / ONE_MILLION;

System.out.println("Clock drift " + drift + " ms after " + interval

+ " ms = " + (drift * 1000 / interval) + " ms/s");

}

}

}

与Thread.sleep()时间的不及格以及中断应该与定时器漂移完全无关。

这两个Java“系统”调用都用作测量 – 一个用于测量挂钟时间的差异,另一个用于测量绝对间隔,所以当实时时钟不改变时,这些值应该改变在非常接近相同的速度,对吧?这是Java中的错误还是弱点或失败?在操作系统或硬件上有什么可以防止Java更准确吗?

我完全期望这些独立测量之间有一些漂移和抖动(**),但我预计每天漂移不到一分钟。每秒1毫秒漂移,如果单调,差不多90秒!我最糟糕的观察漂移可能是十倍。每次运行这个程序时,我会看到第一个测量的漂移。到目前为止,我没有运行程序超过约30分钟。

我期望看到由于抖动而印制的值中的一些小的随机性,但是在程序的几乎所有运行中,我看到差异的稳定增长,通常高达每秒3毫秒,比这几倍增加。

任何版本的Windows都有类似于Linux的机制来调整系统时钟速度,以便将时钟时钟慢慢地与时钟源同步?这样的事情会影响定时器,还是只影响挂钟计时器?

(*)我明白,在某些架构上,System.nanoTime()必须使用与System.currentTimeMillis()相同的机制。我还认为,任何现代Windows服务器都不是这样的硬件架构是公平的。这是不好的假设吗?

(**)当然,System.currentTimeMillis()通常会比System.nanoTime()大得多的抖动,因为它的粒度在大多数系统上不是1毫秒。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值