system.nanotime是纳秒级单调时间源,适用于相对时间测量;优化重点在于定时器结构(如分层时间轮)、减少锁竞争、缓存时间戳、对象复用以降低gc压力。

System.nanoTime 本身不是“需要优化”的对象,而是高精度时间源;真正要优化的是基于它的定时器实现逻辑——尤其在高并发场景下,避免锁竞争、减少对象分配、规避系统调用开销。
用 nanoTime 替代 currentTimeMillis 做时间差计算
System.currentTimeMillis() 受系统时钟调整影响(如 NTP 校正),且分辨率通常只有 10–15ms;而 nanoTime 提供纳秒级单调递增时间戳,适合做相对时间测量(如超时判断、间隔计算)。
- 只用于计算耗时或到期时间差,不用于生成绝对时间戳
- 调用开销极低(现代 JVM 中基本是单条 CPU 指令),可高频调用
- 示例:定时任务是否到期?if (nanoTime() - startTime >= delayNanos) { ... }
避免每 tick 都调用 nanoTime
高频轮询(比如每微秒检查一次)时反复调用 nanoTime 会带来可观的 CPU 开销。更合理的方式是“批量推进 + 缓存当前时间”。
- 在事件循环或调度线程中,每次循环只调用一次 nanoTime,缓存为
now - 所有到期判断、延迟计算都基于这个
now值,而非重复调用 - 对精度要求不极端的场景(如 1ms 级调度),甚至可每 10–100μs 更新一次
now
用分层/分级时间轮替代全局锁队列
传统 PriorityQueue(如 DelayQueue)在高并发插入/删除时存在锁争用和堆调整开销。基于 nanoTime 的高效定时器应采用无锁或低锁结构:
- 哈希时间轮(HashedWheelTimer):将时间槽按固定 tick 划分,任务根据剩余延迟映射到对应槽位;插入 O(1),到期扫描局部链表
- 多级时间轮(Hierarchical Timer Wheel):处理大范围延迟(秒/分/小时),避免大数组浪费
- 关键点:所有时间槽索引计算均基于 nanoTime 差值,而非绝对时间,避免溢出与校准问题
预分配 + 对象复用减少 GC 压力
高频创建定时任务对象(如 Runnable 包装、TimerTask)会导致年轻代 GC 频繁。结合 nanoTime 使用时,应:
- 复用任务节点(Node/Timeout 对象),用 reset 方法重置 delay 和 callback
- 使用 ThreadLocal 或对象池管理定时上下文(如 Netty 的
PooledByteBufAllocator思路) - 避免在定时回调中触发新任务分配(如 lambda 创建闭包),改用静态方法或预设实例
不复杂但容易忽略:nanoTime 是起点,真正的优化落在结构设计、内存模式和并发模型上。用对它,只是第一步。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











