CAS
CAS(Compare-And-Swap)
CAS(Compare-And-Swap,比较并交换)是一种重要的并发编程中的原子操作,用于实现多线程环境下的同步控制。
基本概念
CAS操作包含三个操作数:
- 内存位置(V)
- 预期原值(A)
- 新值(B)
操作逻辑:当且仅当内存位置V的值等于预期原值A时,处理器才会将该位置的值更新为新值B,否则不执行任何操作
工作原理
bool CAS(V, A, B) {
if (V == A) {
V = B;
return true;
}
return false;
}
原子性
整个操作(比较和交换)视为一条指令,不会被别的线程打断,通过 Unsafe 类的 compareAndSwapXxx 来实现的
优缺点
优点:
synchronized 是悲观锁,每次获取资源都要先获得锁,不管有没有线程竞争
虽然 JDK6 以后有锁升级,但是重量级锁已经深入人心了,先这样举例吧,或者想想 ReentrantLock
CAS 没有获取锁的动作,直接尝试修改,也不会有线程上下文切换、唤醒等开销
缺点:
ABA问题(可通过添加版本号解决)
自旋时间长时CPU开销大(所以锁升级过程中不是一直自旋,一定次数后还是会升级为重量级锁)
只能保证一个共享变量的原子操作
AtomicInteger
public class AtomicInteger extends Number implements java.io.Serializable {
// 值
private volatile int value;
// Unsafe 类
private static final Unsafe U = Unsafe.getUnsafe();
// 获取 value 的内存偏移量
private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value");
// 先返回当前值,再 +1(i++)
public final int getAndIncrement() {
return U.getAndAddInt(this, VALUE, 1);
}
// 先 +1,再返回新值(++i)
public final int incrementAndGet() {
return U.getAndAddInt(this, VALUE, 1) + 1;
}
// 先返回当前值,再增加 delta
public final int getAndAdd(int delta) {
return U.getAndAddInt(this, VALUE, delta);
}
// 先增加 delta,再返回新值(i += delta)
public final int addAndGet(int delta) {
return U.getAndAddInt(this, VALUE, delta) + delta;
}
// 先 -1,再返回新值(--i)
public final int decrementAndGet() {
return U.getAndAddInt(this, VALUE, -1) - 1;
}
// 手动 CAS 操作,若当前值等于 expect 则更新为 update
public final boolean compareAndSet(int expectedValue, int newValue) {
return U.compareAndSetInt(this, VALUE, expectedValue, newValue);
}
}

浙公网安备 33010602011771号