system.nanotime()是java中唯一适合微秒级时间差计算的工具,它基于硬件单调计时器、不受系统时钟调整影响、单位为纳秒且分辨率足够;正确用法是两次调用相减得纳秒耗时,再按需转微秒(整除、四舍五入或浮点保留),并避免单次测量、注意jit预热与统计方式。

System.nanoTime() 是 Java 中唯一适合微秒级时间差计算的工具,它不依赖系统时钟,只返回单调递增的纳秒值,专为测量耗时而设计。
为什么 nanoTime 适合高精度时间差
currentTimeMillis() 返回的是“墙上时间”,受系统时钟调整影响,且精度通常只有毫秒级;nanoTime() 则基于硬件计时器(如 Linux 的 CLOCK_MONOTONIC),不受时钟回拨干扰,数值只增不减,两次调用相减的结果稳定可靠。它的单位是纳秒,但实际分辨率因平台而异:Linux 通常为 1–15 纳秒,Windows 可能略低,不过对微秒级测量已足够。
正确获取时间差的三步操作
- 在目标代码块前调用一次 System.nanoTime(),记录起始值
- 执行待测逻辑(避免 I/O、GC、锁竞争等干扰)
- 再调用一次 System.nanoTime(),与起始值相减,得到纳秒级耗时
注意:不要把 nanoTime 值直接当“时间戳”用,也不能和 currentTimeMillis 混算——两者基准不同,相减无意义。
纳秒转微秒的关键细节
纳秒值除以 1000 才得微秒,但除法类型决定精度:
-
整数截断:
long micros = nanos / 1000;—— 结果向下取整,适合日志打点或简单阈值判断(如“是否超 50μs”) -
四舍五入:
long micros = Math.round(nanos / 1000.0);—— 更贴近人对“约多少微秒”的感知,减少统计偏差 -
浮点保留:
double micros = nanos / 1000.0;—— 用于性能分析、绘图或计算分位数,不丢失原始信息
关键陷阱:写成 nanos / 1000 是整数除法,永远丢小数;必须用 1000.0 触发浮点运算。
避免单次测量失真的实用建议
- 单次 nanoTime 调用开销约 10–100 纳秒,测极短操作(如 i++)会严重污染结果
- 应批量执行 N 次目标逻辑,只测一次总耗时,再除以 N
- 正式测量前需预热(如循环执行万次),让 JIT 编译完成、CPU 缓存就绪
- 关注 P95/P99 延迟而非平均值,尾部毛刺更能暴露真实瓶颈
真正需要微秒反馈的场景(如高频交易、游戏帧同步),重点应优化逻辑本身,而不是靠反复计时去“看清”单次行为——那看到的多半是计时器噪声。











