1. Java原子类概述
在多线程编程中,共享变量的线程安全访问是一个核心问题。Java原子类(java.util.concurrent.atomic包)提供了一种无锁的线程安全编程方式,相比传统的synchronized关键字,原子类通常具有更好的性能表现。
原子类的核心思想是利用CPU的CAS(Compare-And-Swap)指令来实现非阻塞算法。CAS是一种乐观锁机制,它包含三个操作数——内存位置(V)、预期原值(A)和新值(B)。当且仅当V的值等于A时,处理器才会将V的值更新为B,否则不执行任何操作。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 原子类核心实现原理
2.1 CAS机制详解
CAS操作是现代CPU提供的一种原子指令,Java通过Unsafe类的本地方法调用这些指令。典型的CAS操作流程如下:
- 从内存位置读取当前值
- 基于当前值计算出新值
- 如果内存位置的值仍然是之前读取的值,则将新值写入
- 如果值已被其他线程修改,则操作失败
java复制// Unsafe类中的CAS方法示例
public final native boolean compareAndSwapInt(
Object o, long offset, int expected, int x);
2.2 原子类内存语义
Java原子类遵循以下内存语义:
- volatile读:每次读取都能看到其他线程的最新写入
- volatile写:写入后对其他线程立即可见
- CAS操作:同时具有读和写的内存语义
这种内存语义保证了原子类的线程安全性,同时避免了锁带来的性能开销。
3. 主要原子类详解
3.1 基本类型原子类
AtomicInteger
最常用的原子类,提供原子性的int值操作:
java复制AtomicInteger counter = new AtomicInteger(0);
// 原子递增
int newValue = counter.incrementAndGet();
// CAS操作
boolean updated = counter.compareAndSet(0, 1);
AtomicLong
与AtomicInteger类似,但针对long类型。在32位系统上,long的读写不是原子性的,AtomicLong解决了这个问题。
AtomicBoolean
原子布尔类,常用于标志位的原子更新:
java复制AtomicBoolean flag = new AtomicBoolean(false);
// 原子设置true
flag.set(true);
// 从false变为true
boolean success = flag.compareAndSet(false, true);
3.2 引用类型原子类
AtomicReference
原子引用类,可以原子性地更新对象引用:
java复制AtomicReference<String> ref = new AtomicReference<>("
