CAS概念

  • 运用在并发场合下,实现不能被打断的数据交换操作
  • 我认为V值应该是X,如果是的话就修改成Y,如果不是就说明被别人修改过,那我就不修改了,避免多人同时修改导致出错,最后返回V的值

模拟CAS代码案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class SimulatedCAS implements Runnable{

private volatile int value;

public synchronized int compareAndSwap(int expectedValue, int newValue) {
int oldValue = value;
if (oldValue == expectedValue) {
value = newValue;
}
return oldValue;
}

public static void main(String[] args) throws InterruptedException {
SimulatedCAS simulatedCAS = new SimulatedCAS();
simulatedCAS.value = 0;
Thread thread1 = new Thread(simulatedCAS,"Thread1");
Thread thread2 = new Thread(simulatedCAS,"Thread2");
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(simulatedCAS.value);
}

@Override
public void run() {
compareAndSwap(0, 1);
}
}
应用场景:
  • 乐观锁
  • 并发容器
  • 原子类
Unsafe类
  • unsafe是CAS的核心类。java无法直接访问底层操作系统,而是通过本地方法访问。jdk中有一个类unsafe,提供了硬件级别的原子操作
  • valueOffset表示的是变量值在内存中的偏移地址,因为Unsafe就是根据内存偏移地址获取数据的原值,我们就可以通过unsafe实现CAS了
java如何利用CAS实现原子操作的
  • Unsafe类中的compareAndSwapInt方法
    • 方法中先想办法拿到变量value在内存中的地址
    • 然后利用指令实现原子性的比较和替换,完成CAS全过程
CAS缺点:
  • ABA问题,比如一个线程改变了值,但是另一个线程把值改了回来,CAS就不知道
  • 自旋时间可能会过长