在Java并发编程中,CAS(Compare-And-Swap,比较并交换)
是一种重要的原子操作,用于实现无锁(lock-free)算法,自旋锁就是用CAS实现的一种锁。CAS操作通过硬件支持,在不使用传统锁的情况下实现线程安全,主要用于并发数据结构和算法中。
学习之前先了解原子类
利用CAS实现自旋锁
示例代码(存在ABA问题):
import java.util.concurrent.atomic.AtomicInteger;
public class CASExample {
private final AtomicInteger atomicInteger = new AtomicInteger(0);
public void increment() {
int oldValue;
int newValue;
do {
oldValue = atomicInteger.get();
newValue = oldValue + 1;
} while (!atomicInteger.compareAndSet(oldValue, newValue));
}
public static void main(String[] args) {
CASExample example = new CASExample();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Final value: " + example.atomicInteger.get());
}
}
示例代码(已解决ABA问题):
import java.util.concurrent.atomic.AtomicStampedReference;
public class ABAExample {
// public AtomicStampedReference(V initialRef, int initialStamp)
private final AtomicStampedReference<Integer> atomicStampedRef = new AtomicStampedReference<>(0, 0);
public void increment() {
int[] stamp = new int[1];
int oldValue;
int newValue;
int oldStamp;
do {
// public V get(int[] stampHolder) 返回当前value与stamp, stamp 存储在长度为1的数组里
oldValue = atomicStampedRef.get(stamp);
oldStamp = stamp[0];
newValue = oldValue + 1;
} while (!atomicStampedRef.compareAndSet(oldValue, newValue, oldStamp, oldStamp + 1));
}
public static void main(String[] args) {
ABAExample example = new ABAExample();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Final value: " + example.atomicStampedRef.getReference());
}
}