System.nanoTime / System.currentTimeMillis = 107 (

2020-05-10 08:35发布

问题:

According to java.lang.System API

currentTimeMillis() Returns the current time in milliseconds

nanoTime() Returns the current value of the running Java Virtual Machine's high resolution time source, in nanoseconds.

Strictly speaking a nanosecond is 1e-9 and millisecond is 1e-3. Therefore, a duration in nanosecs must be a multiple of 1e6 of the same duration in millisecs. This is not the case in practice, what is the reason?

scala> System.nanoTime / System.currentTimeMillis
res0: Long = 107

回答1:

System.nanoTime() has an arbitrary start point; it's not unix epoch. From the Javadoc:

The value returned represents nanoseconds since some fixed but arbitrary origin time

So what you're actually calculating there is:

(unknownOffset + offsetFromEpochInNanos) / offsetFromEpochInMillis

which will almost certainly not be 1e6, unless unknownOffset happens to be arbitrarily zero.

If you can remove the effect of the unknown offset by subtracting the two times, you can see that the ratio is around 1e6:

long nanoStart = System.nanoTime();
long milliStart = System.currentTimeMillis();

Thread.sleep(2000);

long nanoEnd = System.nanoTime();
long milliEnd = System.currentTimeMillis();;

long nanoDelta = nanoEnd - nanoStart;
long milliDelta = milliEnd - milliStart;

System.out.println((double) nanoDelta / milliDelta);

Output (running 5 times):

1000058.3725
1000045.4705
999549.1579210395
1000046.101
1000038.1045

Ideone demo

So, pretty close to 1e6.

Note that it might not be this, because System.currentTimeMillis() doesn't progress smoothly, owing to corrections for clock skew. However, these should be infrequent, so most of the time when you run this code, you'll see roughly 1e6.



标签: java scala