System.currentTimeMillis() 不生成全局唯一时间戳,需结合自增序列等方案实现唯一性:1. 毫秒时间+原子自增序列(单机内唯一),用 AtomicInteger 在同一毫秒内递增避免重复。

System.currentTimeMillis() 本身不生成“全局唯一”的时间戳,它只返回当前毫秒级时间值,重复是可能的,尤其在高并发或系统时钟回拨时。 要实现全局唯一时间戳(常用于分布式 ID、日志追踪、订单号等场景),需在毫秒时间基础上叠加额外区分信息。以下是几种常用且实用的方式:
1. 毫秒时间 + 自增序列(单机内唯一)
在同一毫秒内,用原子计数器(如 AtomicInteger)递增,避免重复:
- 初始化一个 static AtomicInteger seq = new AtomicInteger(0);
- 每次获取时间戳前:long now = System.currentTimeMillis();
- 拼接为:long uniqueId = (now
- 注意重置逻辑:当时间前进,seq 需重置为 0(否则会溢出),可用循环 CAS 或带时间检查的线程安全计数器。
2. 毫秒时间 + 机器标识(多机间区分)
在分布式环境中,不同机器即使时间相同,加上机器 ID 就可保证唯一:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 机器 ID 可来自 IP 哈希、MAC 地址片段、配置文件或注册中心分配;
- 例如:long uniqueId = (now
- 推荐位分配:41 位毫秒时间 + 10 位机器 ID + 12 位序列号(类似 Twitter Snowflake 结构)。
3. 使用现成方案替代手写
不建议从零实现全局唯一时间戳逻辑,推荐直接使用成熟库:
立即学习“Java免费学习笔记(深入)”;
- Snowflake(如 Twitter 的原版、百度 UidGenerator、美团 Leaf):基于时间戳 + workerId + 序列号,毫秒级有序、全局唯一;
- UUID(time-based UUID v1):含时间戳和 MAC/随机节点,但长度长、不可排序;
- Java 17+ 的 ThreadLocalRandom.current().nextLong() 不适合替代——它不带时间语义,也不保证全局唯一。
4. 注意时钟问题(关键陷阱)
单纯依赖 System.currentTimeMillis() 风险很高:
- 系统时钟可能被手动调整或 NTP 同步导致“回拨”,产生重复或乱序;
- 虚拟机中时钟漂移更常见;
- 解决方案:引入逻辑时钟(如 AtomicLong 递增兜底)、监控时钟偏移、或选用支持时钟容错的 ID 生成器(如 Leaf 的 segment 模式或 Snowflake 的等待机制)。

















