在 Java 中,Atomic 类(如 AtomicInteger、AtomicLong、AtomicReference 等)实现原子性,核心依靠的是:
底层硬件支持的原子指令 + CAS(Compare And Swap) + volatile 保证可见性
下面分层说明。
Java 在 java.util.concurrent.atomic 包中提供了一组原子类,例如:
AtomicIntegerAtomicLongAtomicBooleanAtomicReferenceAtomicIntegerArray它们的特点是:
synchronizedCAS 全称:Compare And Swap(比较并交换)
它是一种 CPU 级别的原子指令,语义是:
if (当前值 == 期望值) {
当前值 = 新值
返回成功
} else {
返回失败
}
整个过程是不可中断的。
以 AtomicInteger 为例:
AtomicInteger count = new AtomicInteger(0);
count.incrementAndGet();
incrementAndGet() 内部逻辑类似(简化):
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next)) {
return next;
}
}
}
其中:
compareAndSet(expect, update)
最终调用的是:
Unsafe.compareAndSwapInt(...)
Unsafe 是 Java 提供的底层操作类,可以直接:
Atomic 类内部大量使用 Unsafe。
不同 CPU 提供不同指令:
LOCK CMPXCHG这些指令在硬件层面保证原子性。
Atomic 类中的值通常用:
private volatile int value;
volatile 的作用:
⚠️ 注意:
volatile不保证原子性
但 Atomic 类用 CAS + volatile 组合实现原子性
| 对比项 | synchronized | Atomic |
|---|---|---|
| 是否阻塞 | 是 | 否(自旋) |
| 性能 | 较低 | 较高 |
| 原子性 | 是 | 是 |
| 适用场景 | 复杂逻辑 | 简单变量操作 |
Atomic 更适合:
一个值:
A → B → A
CAS 会认为“没变”。
✅ 解决:
AtomicStampedReference
AtomicMarkableReference
通过版本号 / 标记解决。
CAS 失败会重试,高并发下可能 CPU 消耗大。
Java 的 Atomic 类通过
volatile保证可见性,通过Unsafe调用底层 CAS 指令,在 CPU 硬件层面实现原子操作,从而避免使用锁也能保证线程安全。
如果你愿意,我也可以:
synchronized 和 Atomic 源码LongAdder 为什么比 AtomicLong 快免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。