system.currenttimemillis() 不适合测量程序运行时间,因其基于系统挂钟、非单调、精度低(windows 约 15.6ms)、易受 ntp 校时影响;应使用 system.nanotime() 进行性能测试。

System.currentTimeMillis() 不能精确获取程序运行时间,它返回的是自 1970 年 1 月 1 日 00:00:00 UTC 起的毫秒数,精度受系统时钟限制(通常为 10–16 毫秒),且可能因系统时间调整(如 NTP 同步)而跳变或回拨,不适合测量短时耗时。
为什么 currentTimeMillis 不适合测性能
它基于系统挂钟(wall-clock time),不是单调递增的:
- 操作系统可能校准时间,导致值突然变小或变大
- 在多核 CPU 或虚拟机环境下,不同线程读到的值可能有微小不一致
- 最小分辨率为操作系统决定(Windows 常为 15.6ms,Linux 可达 1ms,但不保证)
推荐用 System.nanoTime() 测运行时间
System.nanoTime() 返回的是纳秒级的、单调递增的计时器值,专为性能测量设计:
- 不受系统时间调整影响,始终向前走
- 分辨率高(通常优于 1 微秒),适合测量毫秒甚至微秒级耗时
- 注意:它不表示真实时间,只用于计算差值(不能用来计算“几点几分”)
示例:
long start = System.nanoTime(); doSomething(); long end = System.nanoTime(); long durationNs = end - start; // 纳秒 long durationMs = durationNs / 1_000_000; // 转毫秒
实际使用中的注意事项
- 避免在循环中反复调用 nanoTime() 测单次极短操作(如一次加法),其本身开销可能接近被测操作
- 测短任务建议多次执行取平均值,并排除前几次 JIT 预热影响
- 若需高精度统计(如微基准测试),优先用 JMH(Java Microbenchmark Harness),它自动处理预热、GC 干扰、指令重排等问题
什么时候还能用 currentTimeMillis()
适合对精度要求不高的场景:
- 记录日志时间戳(用户感知级,毫秒够用)
- 超时控制(如 HTTP 请求 5 秒超时)
- 缓存过期、定时任务触发等依赖真实时间的逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











