开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
今天要解决的是 乐观锁(CAS)带来的ABA问题。
首先介绍乐观锁,顾名思义,乐观锁是一种比较乐观的锁,一般情况下不会发生锁冲突,所以它只会在进行更改操作时才会检查锁冲突,检查到冲突,不做数据修改,没有冲突时才进行修改。
乐观锁通常使用CAS(比较并替换)机制来实现,它包含3部分内容
v:内存中的值
A:预期旧值
B :新值
乐观锁(CAS)在JAVA中应用:Unsafe 和 AtomicXXX类 CAS存在ABA问题: 张三进行转账操作(卡里有100元) 1.第一次点击转账按钮: -50元(V=100,A=100 ,B=50) 2,第二次点击转账按钮:-50元(V=100,A=100 ,B=50) 3.发工资了,+50
当第二次点击和发工资两个操作先 第一次转账 一步执行, 卡里的钱经过了 -50 再 +50 的操作, 但是数字经过运算后的结果和之前一致, 这时第一次转账操作开始运行, 单独使用CAS后,只能对比数字的大小是否一致, 无法判断数字是否经过更改 我们原本的意图是,只转账一次就停止, 需要两次转账里成功一次,另一次再进行 V和A的对比时 发现V已经发生变化而取消 另一次转账 所以单纯的使用 一个V已经没用了,我们需要引入另一个参数来辅助判断V的变化
ABA 问题解决方案: AtomicStampedReference 引入版本号,每次操作后让版本号+1,执行时对比 版本号和值,就可以解决ABA问题
有了版本号之后,就算数字经过几次计算之后值没变,我们可以通过版本号的变动,直到了数字是经过变动的,不进行后序的修改。