一句话概括:Java 的 Atomic 类之所以具备原子性,是因为它们底层依赖 CPU 的原子指令(如 CAS / 锁总线 / 内存屏障),并由 JVM 和硬件共同保证“读—改—写”操作不可被打断。
下面分层说明。
以 AtomicInteger 为例:
AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet();
表面上只是一个 count++,但它是原子操作,不会出现在多线程下读到旧值、写丢更新的问题。
CAS 是一种CPU 级别的原子指令,逻辑是:
if (当前值 == 期望值)
更新为新值
else
不做任何事
Java 中的 Unsafe 类会直接调用 CPU 指令,例如:
LOCK CMPXCHGLDREX / STREXpublic final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
✅ 整个“读—改—写”过程在硬件层面是原子的
i++ 不行?i++;
实际是三步:
ii+1i线程可能被打断,导致:
线程A读 i=1
线程B读 i=1
线程A写 i=2
线程B写 i=2 // 少加一次
Atomic 用 CAS 避免了这个问题。
LOCK 前缀 + 指令
✅ 这些机制由 CPU + JVM + OS 共同保证
i++)private volatile int value;
| 对比项 | synchronized | Atomic |
|---|---|---|
| 是否阻塞 | 是 | 否(自旋) |
| 锁粒度 | 线程级 | 变量级 |
| 适用场景 | 复杂逻辑 | 简单计数/状态 |
⚠️ 高并发下 CAS 自旋过多也会损耗 CPU
Java Atomic 的原子性不是“Java 语言”给的,而是 Unsafe + CAS + CPU 原子指令共同实现的。
如果你愿意,我也可以:
Atomic vs synchronizedLongAdder 为什么更快免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。