CAS操作-用转账来快速理解compareAndSet方法

通过具体的例子来分析 balance.compareAndSet(currentBalance, currentBalance - amount) 这一步骤的工作原理。

示例场景

假设我们有一个初始余额为 100 的 AtomicInteger 对象 balance,两个线程 Thread AThread B 尝试从该余额中分别转出 10 元。

代码片段

private static AtomicInteger balance = new AtomicInteger(100);

public void transfer(int amount) {
    while (true) {
        int currentBalance = balance.get(); // 获取当前余额
        if (currentBalance < amount) {
            break; // 如果余额不足,退出循环
        }
        // 尝试进行比较并设置新的余额
        if (balance.compareAndSet(currentBalance, currentBalance - amount)) {
            break; // 如果成功,则退出循环
        }
    }
}

详细分析

初始状态
  • balance 的初始值为 100。
第一步:两个线程获取当前余额
  1. Thread A 调用 balance.get(),获取当前余额 currentBalance = 100
  2. Thread B 调用 balance.get(),获取当前余额 currentBalance = 100
第二步:两个线程尝试更新余额
  1. Thread A 尝试执行 balance.compareAndSet(100, 90)

    • compareAndSet 检查当前的 balance 值是否等于 100。
    • 如果 balance 值确实是 100,则将 balance 的值设置为 90。
    • 如果 balance 值不是 100,则返回 false,表示操作失败。
  2. 假设 Thread A 成功地将 balance 的值从 100 更新为 90,那么 balance.compareAndSet(100, 90) 返回 trueThread A 退出循环。

  3. 同时,Thread B 也尝试执行 balance.compareAndSet(100, 90)

    • compareAndSet 检查当前的 balance 值是否等于 100。
    • 由于 Thread A 已经将 balance 的值更新为 90,所以 compareAndSet 检查时,balance 的值不再是 100。
    • 因此,balance.compareAndSet(100, 90) 返回 false,表示操作失败。
第三步:Thread B 重新获取余额并尝试更新
  1. 由于 Thread BcompareAndSet 操作失败,它会重新执行 balance.get(),此时获取到的 currentBalance = 90

  2. Thread B 再次尝试执行 balance.compareAndSet(90, 80)

    • compareAndSet 检查当前的 balance 值是否等于 90。
    • 如果 balance 值确实是 90,则将 balance 的值设置为 80。
    • 如果 balance 值不是 90,则返回 false,表示操作失败。
  3. 假设此时 balance 值为 90,Thread B 成功地将 balance 的值从 90 更新为 80,balance.compareAndSet(90, 80) 返回 trueThread B 退出循环。

总结

compareAndSet 方法实现了原子性检查和更新操作,确保在并发环境下,只有一个线程能够成功更新 AtomicInteger 的值,而不会出现竞态条件。这种机制保证了在多个线程尝试同时更新共享变量时,每次只有一个线程能够成功,其他线程必须重新获取最新的值并重试,直到成功为止。

compareAndSet 方法的具体步骤如下:

  1. 获取当前值 currentBalance
  2. 检查当前值是否与期望值相等。
  3. 如果相等,则更新值并返回 true
  4. 如果不相等,则返回 false,并重新尝试。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值