什么是“原子类“ 和 CAS “无锁化编程“?如何解决 CAS 编程中的 ABA 问题?

目录

一、什么是"原子类"?

二、什么是 CAS ?

三、CAS 的 ABA 问题是什么?

四、如何解决 ABA 问题?


一、什么是"原子类"?

  • "原子类"是 Java 标准库提供的 CAS 工具类。存放于 java.util.concurrent.atomic 包中。
  • Java提供了各种数据类型的封装类,这些封装类的方法都是"原子"的,没有加锁,但是可以保证线程安全,高效且不涉及线程阻塞等待。
  • "原子类" 的类名都为 Atomic 开头,以引用类型结尾,如 AtomicInteger。
  • 应注意"原子类"的计算,都是通过调用方法实现的(如自增++,在"原子类"中需要调用 getAndIncrement() 方法)

二、什么是 CAS ?

  • CAS 指 compare and swap,表示比较并交换。CAS 是一个原子的 CPU 指令完成的。
  • CAS 相当于通过一个”原子“的操作,同时完成”读取内存,比较是否相等,修改内存“这三个步骤,达到”无锁化编程“的目的。
  • 比较和交换的是内存和寄存器中的值。
  • CAS 的实现本质上需要 CPU 指令的支持,由操作系统和 JVM 进行了封装。
  • 使用 CAS 不涉及加锁,不会阻塞。合理使用 CAS 可以保证线程安全。但是由于 CAS 操作涉及操作系统底层,使用不当可能带来风险。

以伪代码的方式理解 CAS:

public void method(){
    Integer memoryValue;
    Integer oldValue;
    Integer newValue;
    if(CAS(newValue, oldValue, memoryValue)){
        memoryValue = newValue;
    }
}
public boolean CAS(Integer newValue, Integer oldValue, Integer memoryValue){
    if(oldValue == memoryValue){
        return true;
    }else {
        return false;
    }
}

三、CAS 的 ABA 问题是什么?​​​​​​​

  • CAS 是通过比较当前内存的值是否和寄存器中的值一致,来判断是否为”原子“操作。

  • 但可能出现,B线程先改变了值,又将值再次改回了原值的情况(如先 +1 后马上 -1)。此时在A线程看来,这个值并没有发生改变。这种情况就是 ABA 问题。

  • ABA 问题通常不会导致程序出错,但特殊情况下也会出现问题。


四、如何解决 ABA 问题?

解决 ABA 问题主要通过两种方式:

  1. 约定数据变化只能是单调的(只能增或只能减)。
  2. 引入版本号,版本号只增不减,每次数据发生变化就更改版本号。需要修改数据时,先对比版本号,版本号不一致则认为修改失败。

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值