为什么不能用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.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.7</version>
</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),这样测试的结果会更准一些。

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值