一、什么是CAS?

Compare And Swap,比较并交换
在修改值之前,先比较一下值有没有被别人修改。
update table set column = #{newValue} where id = #{id} and column = #{oldValue}

二、CAS优点
- 无锁(synchronized),无需切换线程,竞争CPU时间片
- 轻量级,适用于并发量不高,多核CPU的场景
三、CAS缺点
- ABA问题
我在修改前,别人偷偷修改了并且又改回了原始值,我比较就通过了,即无法感知别人的修改。

- 自旋开销问题
在高并发下,可能会一直自旋,长时间占用CPU资源
- 共享变量单一问题
只能保证单个共享变量的原子性,不能保证多个共享变量,或者代码块
四、AtomicInteger等原子类(JUC并发包)
volatile + CAS
- volatile保证内存可见性。
- sun.misc.UnSafe类通过一系列用C/C++实现的本地方法操作CPU指令实现CAS。
通过成员变量的内存偏移量,直接读取或设置该成员变量的值(详见《OOP-Klass HotSpot对象模型》)


compareAndSwapInt(Object o, long offset, int expect, int update)
- 读取传入对象
o在内存中偏移量为offset位置的值与期望值expect作比较。 - 相等就把
update值赋值给offset位置的值,方法返回true。 - 不相等,就取消赋值,方法返回
false。
五、CAS使用事项
- ABA问题
增加版本号
数据库:
update table set column = #{value}, version = version + 1 where id = #{id} and version = #{oldVersion}
Java:
java.util.concurrent.atomic.AtomicStampedReference


- 共享变量单一问题
java.util.concurrent.atomic.AtomicReference
把多个成员变量组成一个对象,更新整个对象


跟Atomicinteger和AtomicBoolean原理是一样的,只不过AtomicInteger、AtomicBoolean底层调用的是unsafe.compareAndSwapInt方法CAS操作int的值,而这里是compareAndSwapObject是CAS操作一个内存对象而已

- 循环时间长开销很大问题

另外,也可以通过代码控制,循环达到一定次数,就结束循环,并返回提示用户”操作失败,请稍后重试~“
5万+

被折叠的 条评论
为什么被折叠?



