1 cas 就是并发时,不加锁也能实现,不出问题
2 cas 比较和交换。
如 库存m(内存值)=10,这个时候期望值也是10(就是期望值中间没有被其他线程改过,所以叫期望值,)如果m==期望值10,就交换,把m改为9.就是这个意思.
Cas底层是依赖cpu的cas指令在更新操作前先判断是否被其他线程修改过,如果没有修改则更新,整个操作原子操作。
问题1:ABA问题。
解决办法: 使用版本号,在变量前面追加上版本号,每次变量更新的时候把版本号加1,那么A-B-A 就会变成1A-2B-3A。从Java1.5开始JUC包里提供了一个类AtomicStampedReference来解决ABA问题。AtomicStampedReference类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前版本号是否等于预期版本号,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。
问题2:自旋,消耗性能
问题3:CAS操作是针对一个变量的,如果对多个变量操作,1. 可以.封装成对象类解决。
什么是CAS操作?
compare and swap,CAS操作需要输入两个数值,一个旧值(期望操作前的值)和一个新值,在操作期间先比较旧值有没有发生变化,如果没有发生变化,才交换成新值,发生了变化则不交换。
CAS使用注意事项
(1)CAS需要和volatile配合使用
CAS只能保证变量的原子性,不能保证变量的内存可见性。CAS获取共享变量的值时,需要和volatile配合使用,来保证共享变量的可见性
(2)CAS适用于并发量不高、多核CPU的情况
CPU多核情况下可以同时执行,如果不合适就失败。而并发量过高,会导致自旋重试耗费大量的CPU资源