atomicinteger 可实现线程安全、高性能的单机唯一 id 生成器,通过 incrementandget() 原子递增并设初始偏移(如 1000000)避免语义冲突,满足唯一性与有序性;适用于单 jvm 高并发场景,但不支持分布式全局唯一。

在高并发场景下,用 AtomicInteger 实现简单可靠的唯一 ID 生成器是常见且有效的方式——它利用 CAS(Compare-And-Swap)机制保证线程安全,无需锁,性能好、代码简洁。
核心思路:原子递增 + 初始偏移
直接调用 incrementAndGet() 即可获得严格递增、线程安全的整数 ID。为避免 ID 从 0 或 1 开始带来的语义问题(比如和数据库主键冲突、或被误认为“无效值”),通常设置一个合理的初始值(如 1000000)。
- 每次调用
idGenerator.incrementAndGet()返回下一个唯一整数 - ID 全局单调递增,天然满足“唯一性”和“有序性”要求
- 不依赖系统时间或随机数,无重复、无竞争失败重试开销
基础实现示例
以下是一个轻量级、线程安全的 ID 生成器:
public class SimpleIdGenerator {
private final AtomicInteger id = new AtomicInteger(1_000_000); // 起始 ID
public int nextId() {
return id.incrementAndGet();
}
}
多个线程并发调用 nextId(),返回值绝不会重复,也无需额外同步。
扩展建议:应对更复杂需求
若需支持分布式、持久化、或 ID 包含时间/机器信息等,AtomicInteger 本身不够用,但可在其基础上增强:
-
带前缀或格式化:如生成 "U20240520000001",可用
String.format("U%s%06d", today, nextId()),注意确保nextId()仍由原子变量提供 -
重启不重号:将当前最大 ID 持久化到文件或 DB,启动时读取并设为
AtomicInteger初始值 -
防绕回:对
int类型,到达Integer.MAX_VALUE后会变为负数。生产环境建议用AtomicLong替代,或加阈值检查抛异常
注意事项与边界情况
AtomicInteger 生成的是本地唯一 ID,适用于单 JVM 进程内高并发场景。它不解决跨服务、跨机器的全局唯一问题(此时应考虑 Snowflake、UUID 或中心化发号器)。
- ID 是数字类型,适合做数据库自增主键替代方案,但不可作为外部暴露的敏感标识(缺乏不可预测性)
- 如果应用有多个独立部署的实例,每个实例都用相同初始值,会导致 ID 冲突 → 必须按实例分配不同起始段,或引入机器标识
- 高并发下性能极佳,实测可达数百万次/秒调用,远超
synchronized或ReentrantLock方案
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











