为什么不能用System.currentTimeMillis()计算执行时间?

1. 前提概要
  • System.currentTimeMillis()是系统时间,系统时间修改、闰秒会导致跳动。
  • System.nanoTime()仅用于计算耗时,和系统时间没有强关联。
  • System.nanoTime()单位是纳秒,但不保证有纳秒的精度,但保证精度至少比System.currentTimeMillis()高。
  • UTC时间实际一天可能是86399或86401秒,标准时间是有铯133衰变周期决定的,需要对齐太阳日。
  • Java时间标准(Time-Scale)把每一天都精确的定义为86400秒,会忽略闰秒。
  • Java8开始引入Instant和Duration,使用Java时间标准(Time-Scale)。这两个类是线程安全的。
2. 为什么System.currentTimeMillis()不适合计算执行时间?
因为系统时间修改或者闰秒的问题,currentTimeMillis跳动会导致计算不准确。
3. 可选的方案
3.1 Java8的Instant和Duration

Instant使用Java的时间标准,精确的86400秒,不存在闰秒的问题。

Instant start = Instant.now();
// CODE HERE        
Instant finish = Instant.now();
long timeElapsed = Duration.between(start, finish).toMillis();
3.2 使用Apache Comman Lang里的StopWatch

引入依赖

<dependency>
    <groupId>org.apache.commonsgroupId>
    <artifactId>commons-lang3artifactId>
    <version>3.7version>
dependency>

Java代码

StopWatch watch = new StopWatch();
watch.start();
// CODE HERE
watch.stop();
System.out.println("Time Elapsed: " + watch.getTime());
4. 延伸阅读

JMH(Java Microbenchmark Harness),Java9开始会成为OpenJDK的一部分。JMH会处理JVM热身(warm-up)和代码优化(code-optimization),这样测试的结果会更准一些。

你可能感兴趣的:(java)