AtomicInteger
CAS: compare and swap 比较并交换
public class CAS01 {AtomicInteger atomicInteger=new AtomicInteger(5);public static void main(String[] args) {CAS01 cas01=new CAS01();System.out.println(cas01.atomicInteger.compareAndSet(5,2021)+"\t current atomicInteger is :"+cas01.atomicInteger);System.out.println(cas01.atomicInteger.compareAndSet(5,2008)+"\t current atomicInteger is :"+cas01.atomicInteger);}}
静态方法无法访问非静态变量
所以上面如果atomicInteger没有static修饰,就只能如上
public class CAS01 {public static void main(String[] args) {AtomicInteger atomicInteger=new AtomicInteger(5);//main线程do somethingSystem.out.println(atomicInteger.compareAndSet(5,2021)+"\t current atomicInteger is :"+atomicInteger);System.out.println(atomicInteger.compareAndSet(5,2008)+"\t current atomicInteger is :"+atomicInteger);}}
输出:
true current atomicInteger is :2021
false current atomicInteger is :2021
分析:
main线程将主内存中的atomicInteger拷贝到其工作内存,
然后做一些事情
完事之后就将工作内存的值刷新回主内存
此时主内存中的值依旧是5,与期望值5相同,故将主内存中的值改为更新值2021
同时又有一个线程进行相同的操作,但是此时主内存中的值已经更新为2021,与期望值5不一致
故无法将主内存中的值改为更新值2008
上面的这段话就是compare and swap的流程!
unsafe类
- unsafe类中存在大量的native方法,因而可以直接调用系统底层资源来执行任务
- unsafe类存在于sun.misc包下
- cas操作依赖于unsafe中的方法
valueOffset变量
- 表示value变量在内存中的偏移地址,比如一个对象有一个起始地址,那对象中的变量有对应的相对于起始地址的偏移地址
- unsafe就是根据内存偏移地址获取数据的

value变量
- atomicInteger的初始值就会赋值给value变量(AtomicInteger有参构造方法)
- 该变量使用volatile修饰,保证了多线程中的可见性和禁止指令排序,无法保证原子性
三者结合

CAS
源码
- CAS全称compare-and-swap,为一条cpu并发原语,原语本身由多条指令构成,执行时不允许中断
- 功能:判断内存某个位置的值是否为预期值,如果是则可以将其更改为更新值,整个过程是原子的
- 调用sun.misc.Unsafe类中的cas方法,jvm会帮我们实现cas汇编指令,这是一种完全依赖于硬件的功能,通过它实现原子操作
Unsafe类中的getAndAddInt方法:
public final int getAndAddInt(Object var1, long var2, int var4) {int var5;do {var5 = this.getIntVolatile(var1, var2);} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));return var5;}
分析:
- 如果AtomicInteger调用getAndIncrement时再调用getAndAddInt
- 此时的var和var2分别是AtomicInteger对象和该对象中value变量相对于该对象的偏移地址
- var4为1
- var5 = this.getIntVolatile(var1, var2)表示从主内存中复制共享变量的值到工作内存
- while(…)表示:如果此时主内存中获取的值跟var5相同,则将var加上var4并并更新到主内存,而且返回true,从而退出while循环
- 我的理解就是do while的body会拷贝一次值,然后while的判断条件也会拷贝一次值
- 即开头讲的cas思想结合do while
原子性保证

结合cpu并发原语阐述
缺点:
1.循环时间长开销大
do while中的cas如果一直不成功,即返回false
则会一直循环下去
会给cpu带来很大的开销
2.只能保证一个共享变量的原子操作
cas方法参数中只能操作一个共享变量
如果想保证多个共享变量的原子操作,需要使用synchronized
3.ABA问题

AtomicReference(原子引用)
AtomicInteger对整形进行原子保证
AtomicReference对自定义的类进行原子保证
class User{private int age;private String name;public User(int age,String name){this.name=name;this.age=age;}public String getName(){return this.name;}}public class CAS01 {public static void main(String[] args) {User z3=new User(21,"zhangsan");User l4=new User(10,"lisi");AtomicReference<User> atomicReference=new AtomicReference<>();atomicReference.set(z3);System.out.println(atomicReference.compareAndSet(z3,l4)+"\t current atomicReference is :"+atomicReference.get().getName());System.out.println(atomicReference.compareAndSet(z3,l4)+"\t current atomicReference is :"+atomicReference.get().getName());}}
输出:
true current atomicReference is :lisi
false current atomicReference is :lisi
分析参考AtomicInteger
atomicReference多了set和get方法
ABA问题


