CAS原理

CAS是什么

CAS全称compareAndSwap,比较和交换,是保证多线程操作时的一个原子操作。线程操作时获取到内存的值,在进行修改的时候会传入两个参数,一个修改之前的值,一个修改之后的值,第一个参数用来比较,第二个参数用来交换,只有在第一个参数与内存值比较相同的情况下才会修改成第二个参数,通过一个布尔值看修改成功或失败。

CAS使用

CAS主要应用在并发程序中,多线程修改同一块内存中的变量时就会产生线程安全问题。比如两个线程都要修改一个变量,第一个线程读到这个变量后在还没有修改完成中间第二个线程也都读到了这个变量也会进行修改,两个线程都修改完之后,变量的值替换成第二个线程修改的值,第一个线程修改的值就会被覆盖,这就是线程不安全。此时就需要CAS来保证线程安全,java在jdk1.5引入了CAS,主要代码都放在java.util.concurrent.atomic包中

CAS原理

以比较简单的AtomicInteger为例,我们看一下都有哪些方法:
CAS原理
修改一个int类型变量时,通过途中构造器可以知道用AtomicInteger来包装这个变量,然后通过compareAndSet来修改,看这个方法有两个参数一个是旧值一个是新值,再看方法体是调用了unsafe的compareAndSwapInt方法,而Unsafe类中的方法都是native方法,由JVM本地实现,看到这应该就可以理解了CAS的原理实现。

ABA问题

CAS可以有效的提升并发的效率,但同时也会引入ABA问题。
如线程1从内存X中取出A,这时候另一个线程2也从内存X中取出A,并且线程2进行了一些操作将内存X中的值变成了B,然后线程2又将内存X中的数据变成A,这时候线程1进行CAS操作发现内存X中仍然是A,然后线程1操作成功。虽然线程1的CAS操作成功,但是整个过程就是有问题的。比如链表的头在变化了两次后恢复了原值,但是不代表链表就没有变化。
java中AtomicStampedReference/AtomicMarkableReference来处理会发生ABA问题的场景,主要是在对象中额外再增加一个标记来标识对象是否有过变更。