多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### CAS > Compare and Swap 比较再交换 #### 算法理解 > 无锁算法 > CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 #### ABA问题 在多线程场景下`CAS`会出现`ABA`问题,关于ABA问题这里简单科普下,例如有2个线程同时对同一个值(初始值为A)进行CAS操作,这三个线程如下 1. 线程1,期望值为A,欲更新的值为B 2. 线程2,期望值为A,欲更新的值为B 线程`1`抢先获得CPU时间片,而线程`2`因为其他原因阻塞了,线程`1`取值与期望的A值比较,发现相等然后将值更新为B,然后这个时候**出现了线程`3`,期望值为B,欲更新的值为A**,线程3取值与期望的值B比较,发现相等则将值更新为A,此时线程`2`从阻塞中恢复,并且获得了CPU时间片,这时候线程`2`取值与期望的值A比较,发现相等则将值更新为B,虽然线程`2`也完成了操作,但是线程`2`并不知道值已经经过了`A->B->A`的变化过程。 **`ABA`问题带来的危害**: 小明在提款机,提取了50元,因为提款机问题,有两个线程,同时把余额从100变为50 线程1(提款机):获取当前值100,期望更新为50, 线程2(提款机):获取当前值100,期望更新为50, 线程1成功执行,线程2某种原因block了,这时,某人给小明汇款50 线程3(默认):获取当前值50,期望更新为100, 这时候线程3成功执行,余额变为100, 线程2从Block中恢复,获取到的也是100,compare之后,继续更新余额为50!!! 此时可以看到,实际余额应该为100(100-50+50),但是实际上变为了50(100-50+50-50)这就是ABA问题带来的成功提交。 [实际线程2是不允许成功的,由于没有感知到ABA的过程,导致结果执行了] **解决方法**: 在变量前面加上版本号,每次变量更新的时候变量的**版本号都`+1`**,即`A->B->A`就变成了`1A->2B->3A`。