商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Java 中 System.nanoTime 怎么获取单调的系统时间戳

Java 中 System.nanoTime 怎么获取单调的系统时间戳

  发布于2026-07-04 阅读(0)

扫一扫,手机访问

System.nanoTime() 是 Ja va 中唯一适合高精度性能测量的时间 API,它基于内核单调时钟,具备纳秒级分辨率、单调递增、不受系统时钟调整影响——但请注意,它仅适用于耗时差值计算,不可用于获取绝对时间。 ![Ja va 中 System.nanoTime 怎么获取单调的系统时间戳](http://img.318050.com/uploads/20260701/17828883876a44b7c333c53029072017.webp) **System.nanoTime()** 是 Ja va 中获取单调时间戳的标准方式。它返回的是从某个未指定起点开始的纳秒级计时值,不反映真实世界时间(比如1970年至今),但保证**严格单调递增**,并且不受系统时钟调整(如 NTP 校正、手动改时间)的影响。 ### 为什么 nanoTime 是单调的? 它的底层通常基于高精度、不可逆的硬件计时器(例如 x86 上的 TSC,ARM 上的 CNTPCT_EL0),操作系统将其封装为“单调时钟”(monotonic clock)。这意味着: - 两次调用结果满足:若 t2 在 t1 之后发生,则 nanoTime(t2) ≥ nanoTime(t1) - 即使系统时间被向前或向后修改(比如管理员执行 `date -s`,或 NTP 跳变),nanoTime() 不会回跳或突变 - 它不保证绝对精度(可能有几纳秒到微秒级误差),但差值(duration)非常可靠 ### 怎么正确使用 nanoTime 获取时间间隔? 它只适合测时长,不能直接当“当前时间”用。典型模式是记录起止值再相减: ```ja va long start = System.nanoTime(); doSomeWork(); long end = System.nanoTime(); long durationNs = end - start; // 纳秒级耗时,安全、单调、精确 long durationMs = TimeUnit.NANOSECONDS.toMillis(durationNs); // 转毫秒(注意四舍五入) ``` ⚠️ 注意:不能拿 nanoTime 值和 System.currentTimeMillis() 比较,二者起点和语义完全不同。 ### 常见误区与注意事项 - **不要用作时间戳存储或日志时间**:因为它没有可读性,也无法转换成北京时间 - **避免长时间跨度比较**:虽然理论上单调,但 long 最大值约 9.2E18 纳秒(≈292 年),一般不会溢出;但若程序运行数十年且频繁累加,仍需谨慎 - **JVM 启动后首次调用可能稍慢**:因需初始化底层计时器,但后续调用极快(通常几十纳秒) - **跨 CPU 核心可能有微小偏差**:在某些老硬件或虚拟化环境中,不同核心的 TSC 可能不同步(现代 JVM 和 OS 通常已做校准) ### 替代方案对比 如果你需要“既单调又带时区”的时间戳,应组合使用: - 用 System.nanoTime() 测量性能、计算延迟、实现超时逻辑 - 用 System.currentTimeMillis() 或 Instant.now() 记录事件发生时刻(注意:它们可能跳变) - 高精度+单调+可读时间?考虑 Clock.tickNanos(Clock.systemUTC(), Duration.ofNanos(1))(Ja va 9+),但本质仍是包装 nanoTime,不改变其无日期特性
本文转载于:https://www.php.cn/faq/2750024.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注