JDK 8 CAS(Compare-And-Swap)源码详解(详细注释版)
1. CAS基本概念
/*
* CAS (Compare-And-Swap) 比较并交换
* 是一种无锁的原子操作算法
* CAS操作包含三个操作数:
* - 内存位置(V)
* - 预期原值(A)
* - 新值(B)
*
* CAS操作的语义是:如果内存位置V的值等于预期原值A,则将内存位置V的值更新为新值B,
* 否则不进行任何操作。整个比较和替换操作是原子性的。
*
* CAS广泛应用于Java并发编程中,是实现无锁算法的基础。
*/
/**
* CAS操作的基本流程:
* 1. 获取当前内存位置的值
* 2. 比较当前值与预期值是否相等
* 3. 如果相等,则更新为新值
* 4. 如果不相等,则不更新
* 5. 返回操作是否成功
*/
2. Unsafe类中的CAS方法
/*
* sun.misc.Unsafe类提供了底层的CAS操作
* 这些方法直接调用CPU的CAS指令
*/
public final class Unsafe {
/**
* 比较并交换对象字段的int值
*
* @param obj 对象实例
* @param offset 字段在对象中的偏移量
* @param expect 预期值
* @param update 新值
* @return 如果交换成功返回true,否则返回false
*/
public final native boolean compareAndSwapInt(Object obj, long offset,
int expect, int update);
/**
* 比较并交换对象字段的long值
*
* @param obj 对象实例
* @param offset 字段在对象中的偏移量
* @param expect 预期值
* @param update 新值
* @return 如果交换成功返回true,否则返回false
*/
public final native boolean compareAndSwapLong(Object obj, long offset,
long expect, long update);
/**
* 比较并交换对象字段的引用值
*
* @param obj 对象实例
* @param offset 字段在对象中的偏移量
* @param expect 预期引用
* @param update 新引用
* @return 如果交换成功返回true,否则返回false
*/
public final native boolean compareAndSwapObject(Object obj, long offset,
Object expect, Object update);
/**
* 原子递增并获取int字段的值
*
* @param obj 对象实例
* @param offset 字段在对象中的偏移量
* @param delta 增量
* @return 递增后的新值
*/
public final int getAndAddInt(Object obj, long offset, int delta) {
int v;
do {
// 获取当前值
v = getIntVolatile(obj, offset);
// 循环CAS直到成功
} while (!compareAndSwapInt(obj, offset, v, v + delta));
return v;
}
/**
* 原子递增并获取long字段的值
*
* @param obj 对象实例
* @param offset 字段在对象中的偏移量
* @param delta 增量
* @return 递增后的新值
*/
public final long getAndAddLong(Object obj, long offset, long delta) {
long v;
do {
// 获取当前值
v = getLongVolatile(obj, offset);
// 循环CAS直到成功
} while (!compareAndSwapLong(obj, offset, v, v + delta));
return v;
}
/**
* 原子设置int字段的值并返回旧值
*
* @param obj 对象实例
* @param offset 字段在对象中的偏移量
* @param newValue 新值
* @return 旧值
*/
public final int getAndSetInt(Object obj, long offset, int newValue) {
int v;
do {
// 获取当前值
v = getIntVolatile(obj, offset);
// 循环CAS直到成功
} while (!compareAndSwapInt(obj, offset, v, newValue));
return v;
}
/**
* 原子设置long字段的值并返回旧值
*
* @param obj 对象实例
* @param offset 字段在对象中的偏移量
* @param newValue 新值
* @return 旧值
*/
public final long getAndSetLong(Object obj, long offset, long newValue) {
long v;
do {
// 获取当前值
v = getLongVolatile(obj, offset);
// 循环CAS直到成功
} while (!compareAndSwapLong(obj, offset, v, newValue));
return v;
}
/**
* 原子设置对象字段的引用值并返回旧引用
*
* @param obj 对象实例
* @param offset 字段在对象中的偏移量
* @param newValue 新引用
* @return 旧引用
*/
public final Object getAndSetObject(Object obj, long offset, Object newValue) {
Object v;
do {
// 获取当前引用
v = getObjectVolatile(obj, offset);
// 循环CAS直到成功
} while (!compareAndSwapObject(obj, offset, v, newValue));
return v;
}
// 以下是一些volatile访问方法
public native int getIntVolatile(Object obj, long offset);
public native void putIntVolatile(Object obj, long offset, int value);
public native long getLongVolatile(Object obj, long offset);
public native void putLongVolatile(Object obj, long offset, long value);
public native Object getObjectVolatile(Object obj, long offset);
public native void putObjectVolatile(Object obj, long offset, Object value);
// 有序写入方法(不保证对其他线程立即可见)
public native void putOrderedInt(Object obj, long offset, int value);
public native void putOrderedLong(Object obj, long offset, long value);
public native void putOrderedObject(Object obj, long offset, Object value);
}
3. AtomicInteger源码分析
/*
* AtomicInteger是CAS应用的典型例子
* 提供了原子性的int操作
*/
public class AtomicInteger extends Number implements java.io.Serializable {
// 序列化版本UID
private static final long serialVersionUID = 6214790243416807050L;
// 获取Unsafe实例
private static final Unsafe unsafe = Unsafe.getUnsafe();
// value字段的偏移量
private static final long valueOffset;
static {
try {
// 获取value字段在对象中的偏移量
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex);
}
}
// 实际存储的int值,使用volatile保证可见性
private volatile int value;
/**
* 构造方法 - 初始化为0
*/
public AtomicInteger() {
}
/**
* 构造方法 - 指定初始值
*
* @param initialValue 初始值
*/
public AtomicInteger(int initialValue) {
value = initialValue;
}
/**
* 获取当前值
*
* @return 当前值
*/
public final int get() {
return value;
}
/**
* 设置新值
*
* @param newValue 新值
*/
public final void set(int newValue) {
value = newValue;
}
/**
* 原子性地设置新值,并返回旧值
*
* @param newValue 新值
* @return 旧值
*/
public final int getAndSet(int newValue) {
return unsafe.getAndSetInt(this, valueOffset, newValue);
}
/**
* 原子性地比较并设置值
* 如果当前值等于预期值,则更新为新值
*
* @param expect 预期值
* @param update 新值
* @return 如果成功设置返回true,否则返回false
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
/**
* 弱化的比较并设置
* 在某些平台可能不保证原子性,但通常与compareAndSet相同
*
* @param expect 预期值
* @param update 新值
* @return 如果成功设置返回true,否则返回false
*/
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
/**
* 原子性地递增并返回旧值
*
* @return 递增前的值
*/
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
/**
* 原子性地递减并返回旧值
*
* @return 递减前的值
*/
public final int getAndDecrement() {
return unsafe.getAndAddInt(this, valueOffset, -1);
}
/**
* 原子性地增加指定值并返回旧值
*
* @param delta 要增加的值
* @return 增加前的值
*/
public final int getAndAdd(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta);
}
/**
* 原子性地递增并返回新值
*
* @return 递增后的值
*/
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
/**
* 原子性地递减并返回新值
*
* @return 递减后的值
*/
public final int decrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
}
/**
* 原子性地增加指定值并返回新值
*
* @param delta 要增加的值
* @return 增加后的值
*/
public final int addAndGet(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
}
/**
* 原子性地更新值,使用给定的更新函数
*
* @param updateFunction 更新函数
* @return 更新后的值
*/
public final int updateAndGet(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return next;
}
/**
* 原子性地更新值,使用给定的更新函数,并返回旧值
*
* @param updateFunction 更新函数
* @return 更新前的值
*/
public final int getAndUpdate(IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get();
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(prev, next));
return prev;
}
/**
* 带内存语义的获取操作
*
* @return 当前值
*/
public final int getPlain() {
return value;
}
/**
* 带内存语义的设置操作
*
* @param newValue 新值
*/
public final void setPlain(int newValue) {
value = newValue;
}
/**
* 带volatile语义的获取操作
*
* @return 当前值
*/
public final int getOpaque() {
return value;
}
/**
* 带volatile语义的设置操作
*
* @param newValue 新值
*/
public final void setOpaque(int newValue) {
value = newValue;
}
/**
* 带release语义的设置操作
*
* @param newValue 新值
*/
public final void setRelease(int newValue) {
unsafe.putOrderedInt(this, valueOffset, newValue);
}
/**
* 带acquire语义的获取操作
*
* @return 当前值
*/
public final int getAcquire() {
return value;
}
}
4. AtomicReference源码分析
/*
* AtomicReference提供对引用类型的原子操作
*/
public class AtomicReference<V> implements java.io.Serializable {
private static final long serialVersionUID = -1848883965231344442L;
// 获取Unsafe实例
private static final Unsafe unsafe = Unsafe.getUnsafe();
// value字段的偏移量
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicReference.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex);
}
}
// 实际存储的引用值,使用volatile保证可见性
private volatile V value;
/**
* 构造方法 - 初始化为null
*/
public AtomicReference() {
}
/**
* 构造方法 - 指定初始值
*
* @param initialValue 初始引用值
*/
public AtomicReference(V initialValue) {
value = initialValue;
}
/**
* 获取当前引用值
*
* @return 当前引用值
*/
public final V get() {
return value;
}
/**
* 设置新引用值
*
* @param newValue 新引用值
*/
public final void set(V newValue) {
value = newValue;
}
/**
* 原子性地设置新引用值,并返回旧引用值
*
* @param newValue 新引用值
* @return 旧引用值
*/
public final V getAndSet(V newValue) {
return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
}
/**
* 原子性地比较并设置引用值
* 如果当前引用值等于预期引用值,则更新为新引用值
*
* @param expect 预期引用值
* @param update 新引用值
* @return 如果成功设置返回true,否则返回false
*/
public final boolean compareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}
/**
* 弱化的比较并设置
*
* @param expect 预期引用值
* @param update 新引用值
* @return 如果成功设置返回true,否则返回false
*/
public final boolean weakCompareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}
/**
* 原子性地更新引用值,使用给定的更新函数
*
* @param updateFunction 更新函数
* @return 更新后的引用值
*/
public final V updateAndGet(UnaryOperator<V> updateFunction) {
V prev, next;
do {
prev = get();
next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return next;
}
/**
* 原子性地更新引用值,使用给定的更新函数,并返回旧值
*
* @param updateFunction 更新函数
* @return 更新前的引用值
*/
public final V getAndUpdate(UnaryOperator<V> updateFunction) {
V prev, next;
do {
prev = get();
next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return prev;
}
}
5. ABA问题及解决方案
/*
* ABA问题演示和解决方案
*/
/**
* ABA问题演示
* 线程1:读取值A -> 线程2:修改为B -> 线程2:再修改回A -> 线程1:CAS成功(但中间状态已改变)
*/
public class ABADemo {
// 使用AtomicInteger演示ABA问题
private static AtomicInteger atomicInt = new AtomicInteger(10);
public static void abaProblemDemo() {
// 线程1获取值
int value1 = atomicInt.get(); // 10
// 线程2修改值
atomicInt.compareAndSet(10, 20); // 10 -> 20
atomicInt.compareAndSet(20, 10); // 20 -> 10
// 线程1执行CAS,虽然值又变回10,但中间状态已改变
boolean success = atomicInt.compareAndSet(10, 30); // 会成功
System.out.println("CAS success: " + success); // true
System.out.println("Final value: " + atomicInt.get()); // 30
}
}
/**
* AtomicStampedReference解决ABA问题
* 通过版本号来解决ABA问题
*/
public class AtomicStampedReference<V> {
private static class Pair<T> {
final T reference;
final int stamp;
Pair(T reference, int stamp) {
this.reference = reference;
this.stamp = stamp;
}
}
private volatile Pair<V> pair;
/**
* 构造方法
*
* @param initialRef 初始引用值
* @param initialStamp 初始版本号
*/
public AtomicStampedReference(V initialRef, int initialStamp) {
pair = new Pair<V>(initialRef, initialStamp);
}
/**
* 获取当前引用值
*
* @return 当前引用值
*/
public V getReference() {
return pair.reference;
}
/**
* 获取当前版本号
*
* @return 当前版本号
*/
public int getStamp() {
return pair.stamp;
}
/**
* 获取引用值和版本号
*
* @param stampHolder 用于存储版本号的数组
* @return 当前引用值
*/
public V get(int[] stampHolder) {
Pair<V> pair = this.pair;
stampHolder[0] = pair.stamp;
return pair.reference;
}
/**
* 原子性地比较并设置引用值和版本号
*
* @param expectedReference 预期引用值
* @param newReference 新引用值
* @param expectedStamp 预期版本号
* @param newStamp 新版本号
* @return 如果成功设置返回true,否则返回false
*/
public boolean compareAndSet(V expectedReference,
V newReference,
int expectedStamp,
int newStamp) {
Pair<V> current = pair;
return
expectedReference == current.reference &&
expectedStamp == current.stamp &&
(newReference == current.reference && newStamp == current.stamp ||
casPair(current, new Pair<V>(newReference, newStamp)));
}
/**
* CAS更新Pair对象
*/
private boolean casPair(Pair<V> cmp, Pair<V> val) {
return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
}
private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
private static final long pairOffset =
objectFieldOffset(UNSAFE, AtomicStampedReference.class, "pair");
private static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
Class<?> c, String fieldName) {
try {
return UNSAFE.objectFieldOffset(c.getDeclaredField(fieldName));
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
}
/**
* 使用AtomicStampedReference解决ABA问题的示例
*/
public class ABASolutionDemo {
private static AtomicStampedReference<Integer> stampedRef =
new AtomicStampedReference<>(10, 0);
public static void solveABAProblem() {
// 获取当前值和版本号
int[] stampHolder = new int[1];
Integer value1 = stampedRef.get(stampHolder);
int stamp1 = stampHolder[0];
// 线程2修改值和版本号
stampedRef.compareAndSet(10, 20, stamp1, stamp1 + 1);
stampedRef.compareAndSet(20, 10, stamp1 + 1, stamp1 + 2);
// 线程1执行CAS,现在会失败因为版本号不匹配
boolean success = stampedRef.compareAndSet(10, 30, stamp1, stamp1 + 3);
System.out.println("CAS success: " + success); // false
// 正确的方式:使用当前的版本号
Integer currentValue = stampedRef.get(stampHolder);
int currentStamp = stampHolder[0];
success = stampedRef.compareAndSet(currentValue, 30, currentStamp, currentStamp + 1);
System.out.println("Correct CAS success: " + success); // true
}
}
6. 自旋锁实现示例
/**
* 基于CAS的自旋锁实现
*/
public class SpinLock {
// 使用AtomicReference存储锁的拥有者线程
private AtomicReference<Thread> owner = new AtomicReference<>();
/**
* 获取锁
*/
public void lock() {
Thread current = Thread.currentThread();
// 自旋获取锁
while (!owner.compareAndSet(null, current)) {
// 如果CAS失败,继续自旋
}
}
/**
* 释放锁
*/
public void unlock() {
Thread current = Thread.currentThread();
// 释放锁
owner.compareAndSet(current, null);
}
}
/**
* 改进的自旋锁,支持重入
*/
public class ReentrantSpinLock {
private AtomicReference<Thread> owner = new AtomicReference<>();
private AtomicInteger count = new AtomicInteger(0);
/**
* 获取锁
*/
public void lock() {
Thread current = Thread.currentThread();
// 如果当前线程已经持有锁,增加计数
if (owner.get() == current) {
count.incrementAndGet();
return;
}
// 自旋获取锁
while (!owner.compareAndSet(null, current)) {
// 自旋等待
}
count.set(1);
}
/**
* 释放锁
*/
public void unlock() {
Thread current = Thread.currentThread();
// 只有锁的拥有者才能释放锁
if (owner.get() == current) {
if (count.get() == 1) {
// 最后一次释放,真正释放锁
owner.compareAndSet(current, null);
count.set(0);
} else {
// 减少重入计数
count.decrementAndGet();
}
}
}
}
7. CAS在并发容器中的应用
/**
* 简化的无锁栈实现
* 演示CAS在并发数据结构中的应用
*/
public class ConcurrentStack<E> {
// 栈顶节点
private AtomicReference<Node<E>> top = new AtomicReference<>();
// 节点内部类
private static class Node<E> {
final E item;
Node<E> next;
Node(E item) {
this.item = item;
}
}
/**
* 入栈操作
*
* @param item 要入栈的元素
*/
public void push(E item) {
Node<E> newNode = new Node<>(item);
Node<E> currentTop;
do {
currentTop = top.get();
newNode.next = currentTop;
} while (!top.compareAndSet(currentTop, newNode));
}
/**
* 出栈操作
*
* @return 栈顶元素,如果栈为空返回null
*/
public E pop() {
Node<E> currentTop;
Node<E> newTop;
do {
currentTop = top.get();
if (currentTop == null) {
return null;
}
newTop = currentTop.next;
} while (!top.compareAndSet(currentTop, newTop));
return currentTop.item;
}
/**
* 获取栈大小(近似值)
*
* @return 栈中元素数量的近似值
*/
public int size() {
int count = 0;
Node<E> current = top.get();
while (current != null) {
count++;
current = current.next;
}
return count;
}
}
/**
* 简化的无锁队列实现
*/
public class ConcurrentQueue<E> {
// 头节点和尾节点
private AtomicReference<Node<E>> head = new AtomicReference<>();
private AtomicReference<Node<E>> tail = new AtomicReference<>();
// 节点内部类
private static class Node<E> {
final E item;
AtomicReference<Node<E>> next = new AtomicReference<>();
Node(E item) {
this.item = item;
}
}
/**
* 构造方法
*/
public ConcurrentQueue() {
Node<E> dummy = new Node<>(null);
head.set(dummy);
tail.set(dummy);
}
/**
* 入队操作
*
* @param item 要入队的元素
*/
public void enqueue(E item) {
Node<E> newNode = new Node<>(item);
Node<E> currentTail;
Node<E> currentTailNext;
while (true) {
currentTail = tail.get();
currentTailNext = currentTail.next.get();
// 检查tail是否一致
if (currentTail == tail.get()) {
if (currentTailNext != null) {
// tail指针滞后,推进tail
tail.compareAndSet(currentTail, currentTailNext);
} else {
// 尝试插入新节点
if (currentTail.next.compareAndSet(null, newNode)) {
// 插入成功,推进tail
tail.compareAndSet(currentTail, newNode);
return;
}
}
}
}
}
/**
* 出队操作
*
* @return 队首元素,如果队列为空返回null
*/
public E dequeue() {
Node<E> currentHead;
Node<E> currentTail;
Node<E> currentHeadNext;
while (true) {
currentHead = head.get();
currentTail = tail.get();
currentHeadNext = currentHead.next.get();
// 检查head是否一致
if (currentHead == head.get()) {
if (currentHead == currentTail) {
// 队列为空或只有一个元素
if (currentHeadNext == null) {
return null; // 队列为空
}
// tail指针滞后,推进tail
tail.compareAndSet(currentTail, currentHeadNext);
} else {
// 读取值并推进head
E item = currentHeadNext.item;
if (head.compareAndSet(currentHead, currentHeadNext)) {
return item;
}
}
}
}
}
}
8. CAS性能分析和注意事项
/**
* CAS性能测试示例
*/
public class CASTest {
private static final int THREAD_COUNT = 10;
private static final int INCREMENT_COUNT = 1000000;
// 测试AtomicInteger性能
private static AtomicInteger atomicCounter = new AtomicInteger(0);
// 测试synchronized性能
private static int syncCounter = 0;
private static final Object lock = new Object();
public static void performanceTest() throws InterruptedException {
// 测试AtomicInteger
long startTime = System.currentTimeMillis();
Thread[] atomicThreads = new Thread[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
atomicThreads[i] = new Thread(() -> {
for (int j = 0; j < INCREMENT_COUNT; j++) {
atomicCounter.incrementAndGet();
}
});
atomicThreads[i].start();
}
for (Thread thread : atomicThreads) {
thread.join();
}
long atomicTime = System.currentTimeMillis() - startTime;
// 测试synchronized
startTime = System.currentTimeMillis();
Thread[] syncThreads = new Thread[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
syncThreads[i] = new Thread(() -> {
for (int j = 0; j < INCREMENT_COUNT; j++) {
synchronized (lock) {
syncCounter++;
}
}
});
syncThreads[i].start();
}
for (Thread thread : syncThreads) {
thread.join();
}
long syncTime = System.currentTimeMillis() - startTime;
System.out.println("AtomicInteger time: " + atomicTime + "ms");
System.out.println("Synchronized time: " + syncTime + "ms");
System.out.println("AtomicInteger result: " + atomicCounter.get());
System.out.println("Synchronized result: " + syncCounter);
}
}
/**
* CAS使用注意事项
*/
public class CASBestPractices {
/**
* 1. 避免ABA问题
* 使用AtomicStampedReference或AtomicMarkableReference
*/
public void avoidABA() {
AtomicStampedReference<Integer> stampedRef =
new AtomicStampedReference<>(1, 0);
// 使用版本号避免ABA问题
}
/**
* 2. 避免过度自旋
* 在高竞争情况下,CAS失败率高,自旋消耗CPU
*/
public void avoidBusySpin() {
AtomicBoolean lock = new AtomicBoolean(false);
// 不好的实现
/*
while (!lock.compareAndSet(false, true)) {
// 空循环,消耗CPU
}
*/
// 好的实现
while (!lock.compareAndSet(false, true)) {
Thread.yield(); // 让出CPU时间片
// 或者使用LockSupport.parkNanos(1); // 短暂阻塞
}
}
/**
* 3. 注意内存可见性
* 使用volatile字段确保内存可见性
*/
public void memoryVisibility() {
// AtomicInteger内部使用volatile确保可见性
AtomicInteger counter = new AtomicInteger(0);
}
/**
* 4. 合理使用弱CAS
* 在某些平台,weakCompareAndSet可能更高效
*/
public void weakCAS() {
AtomicInteger counter = new AtomicInteger(0);
// 在某些情况下使用weakCompareAndSet
counter.weakCompareAndSet(0, 1);
}
/**
* 5. 注意ABA问题的实际影响
* 不是所有场景都需要解决ABA问题
*/
public void whenToSolveABA() {
// 对于简单的计数器,ABA问题通常不影响结果
AtomicInteger counter = new AtomicInteger(0);
// 对于指针或引用,ABA问题可能影响正确性
AtomicReference<Node> head = new AtomicReference<>();
}
}
9. 核心设计要点总结
9.1 CAS算法原理
- Compare: 比较内存位置的当前值与预期值
- And: 如果相等则继续
- Swap: 将内存位置的值更新为新值
- 整个操作是原子性的
9.2 优势
- 无锁: 不需要操作系统层面的锁机制
- 高性能: 在低竞争情况下性能优于传统锁
- 非阻塞: 线程不会被阻塞,减少上下文切换
9.3 劣势
- ABA问题: 值从A变为B再变为A时可能产生问题
- 自旋消耗: 高竞争情况下CPU消耗大
- 只能保证一个共享变量的原子操作: 需要额外机制保证多个变量
9.4 应用场景
- 原子计数器: AtomicInteger等
- 无锁数据结构: 无锁栈、队列等
- 自旋锁: 轻量级锁实现
- 并发容器: ConcurrentHashMap等
9.5 最佳实践
- 合理评估竞争程度选择CAS或传统锁
- 注意ABA问题并选择合适的解决方案
- 避免过度自旋,适当使用Thread.yield()
- 确保共享变量使用volatile保证可见性
CAS作为现代并发编程的基础,为Java并发包提供了高性能的无锁算法实现,是理解Java并发机制的重要基础。