CAS
什么是CAS
compareAndSet的缩写,比较并交换。
如果达到期望值,那么就更新,否则,就不更新。
通过例子来解释一下:
package com.cc.cas;
import java.util.concurrent.atomic.AtomicInteger;
public class CASDemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
//+1操作,这里值由2021变为了2022
atomicInteger.getAndIncrement();
//期待值为2020,显然现有的值跟期待值不等,不更新,返回false
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
}
}
运行结果:
true
2021
false
2022
Unsafe类
getAndAddInt这里是一个自旋锁,关于锁的介绍在后文。
小结一下
CAS:比较当前工作内存中的值与主内存中的值,如果值是期望的,那么执行更新操作,否则就一直循环。
这样看来那肯定是有缺点的:
1、循环会耗时
扫描二维码关注公众号,回复:
11132770 查看本文章
2、一次性只能保证一个共享变量的原子性
3、可能会导致ABA问题
ABA问题
变量A=1, 线程一要进行cas(1,2)交换,在还没有执行成功之前,这时来了一个线程二,执行了cas(1,3),紧接着又执行了cas(3,1),那么最后的A的值还是1,但是这时线程一是不知道A的值已经被修改过。
通过代码模拟一下:
package com.cc.cas;
import java.util.concurrent.atomic.AtomicInteger;
public class CASDemo {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
//=========捣乱的线程==========
System.out.println(atomicInteger.compareAndSet(2021, 2020));
System.out.println(atomicInteger.get());
System.out.println(atomicInteger.compareAndSet(2020, 9999));
System.out.println(atomicInteger.get());
}
}
运行结果:
true
2021
true
2020
true
9999