一、AtomicReference
1. 核心功能
- 原子更新对象引用:确保对引用变量的修改(如赋值、交换)是线程安全的。
- 适用场景:单变量的原子操作,无需关心引用被修改的历史状态。
2. 代码示例:无锁栈实现
public class ConcurrentStack<T> {
private AtomicReference<Node<T>> top = new AtomicReference<>();
public void push(T item) {
Node<T> newHead = new Node<>(item);
Node<T> oldHead;
do {
oldHead = top.get();
newHead.next = oldHead;
} while (!top.compareAndSet(oldHead, newHead));
}
public T pop() {
Node<T> oldHead;
Node<T> newHead;
do {
oldHead = top.get();
if (oldHead == null) return null;
newHead = oldHead.next;
} while (!top.compareAndSet(oldHead, newHead));
return oldHead.item;
}
private static class Node<T> {
final T item;
Node<T> next;
Node(T item) { this.item = item; }
}
}
3. 局限性
- ABA问题:若引用从
A
→B
→A
,CAS无法感知中间状态变化,可能导致逻辑错误。
二、AtomicStampedReference
1. 核心功能
- 解决ABA问题:通过关联一个
int
类型的版本号(Stamp),跟踪引用的修改次数。 - 适用场景:需要严格检测引用是否被修改过的场景(如无锁链表、队列)。
2. 代码示例:ABA问题防护
public class ABADemo {
private AtomicStampedReference<String> ref =
new AtomicStampedReference<>("A", 0);
public void update() {
int[] stampHolder = new int[1];
String current = ref.get(stampHolder);
int newStamp = stampHolder[0] + 1;
ref.compareAndSet(current, "B", stampHolder[0], newStamp);
}
public boolean isModified() {
return ref.getStamp() > 0;
}
}
3. 实现机制
- 内部存储:一个对象引用 + 一个
int
版本号,两者绑定更新。 - 原子操作:同时比较引用和版本号,确保二者均符合预期才更新。
三、AtomicMarkableReference
1. 核心功能
- 简化状态追踪:通过一个
boolean
标记位记录引用是否被修改过。 - 适用场景:仅需知道引用是否变化,无需精确版本号的场景(如资源状态标记)。
2. 代码示例:缓存失效标记
public class Cache<T> {
private AtomicMarkableReference<T> data =
new AtomicMarkableReference<>(null, false);
public void updateCache(T newData) {
data.set(newData, true);
}
public T getCache() {
boolean[] markHolder = { false };
T value = data.get(markHolder);
return markHolder[0] ? value : null;
}
}
3. 实现机制
- 内部存储:一个对象引用 + 一个
boolean
标记位,两者绑定更新。 - 原子操作:同时比较引用和标记位,确保二者均符合预期才更新。