CAS算法:无锁并发的基石
CAS算法:无锁并发的基石
概述
CAS(Compare And Swap)是一种无锁的并发算法,它通过比较并交换的方式实现原子操作,是Java并发包的基础。
1. CAS原理
import java.util.concurrent.atomic.AtomicInteger;
public class CASDemo {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
public static void main(String[] args) throws InterruptedException {
CASDemo demo = new CASDemo();
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < 1000; j++) {
demo.increment();
}
});
threads[i].start();
}
for (Thread t : threads) {
t.join();
}
System.out.println("Count: " + demo.getCount());
}
}
2. 原子变量类
import java.util.concurrent.atomic.*;
public class AtomicVariableDemo {
private AtomicInteger intCount = new AtomicInteger(0);
private AtomicLong longCount = new AtomicLong(0L);
private AtomicReference<User> userRef = new AtomicReference<>();
private AtomicStampedReference<Integer> stampedRef = new AtomicStampedReference<>(0, 0);
public void demo() {
intCount.incrementAndGet();
intCount.compareAndSet(10, 20);
longCount.addAndGet(100L);
userRef.set(new User("John"));
userRef.compareAndSet(new User("John"), new User("Jane"));
}
}
3. ABA问题
// ABA问题:值从A变为B,再变回A,CAS会认为没有变化
// 解决:使用AtomicStampedReference
public class ABAProblemDemo {
private AtomicStampedReference<Integer> ref = new AtomicStampedReference<>(0, 0);
public void solveABA() {
int stamp = ref.getStamp();
Integer value = ref.getReference();
ref.compareAndSet(value, value + 1, stamp, stamp + 1);
}
}
4. Unsafe类
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class UnsafeDemo {
private static Unsafe unsafe;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
} catch (Exception e) { e.printStackTrace(); }
}
public static void main(String[] args) {
int[] value = {0};
unsafe.compareAndSwapInt(value, 0, 0, 1);
System.out.println(value[0]);
}
}
5. LongAdder
import java.util.concurrent.atomic.LongAdder;
public class LongAdderDemo {
private LongAdder adder = new LongAdder();
public void increment() {
adder.increment();
}
public long getCount() {
return adder.sum();
}
}
最佳实践
- 使用Atomic*类:简单原子操作优先使用
- 解决ABA问题:使用AtomicStampedReference
- 高并发场景:使用LongAdder替代AtomicLong
- 理解CAS原理:有助于理解并发包的实现
- 避免CAS循环:设置重试次数限制
总结
CAS是Java并发包的基础算法,它通过无锁的方式实现原子操作,提高了并发性能。掌握CAS原理和原子变量的使用,是理解Java并发编程的重要基础。