多线程CAS以及ABA问题

本文介绍了CAS(CompareandSwap)操作在面试中的重要性,特别是在处理ABA问题时。它是一种无锁编程方法,通过原子指令实现线程安全,但代码复杂度高且适用于特定场景。此外,文章还讨论了ABA问题的原理以及如何通过增加版本号来避免它。
摘要由CSDN通过智能技术生成

目录

CAS(M,A,B)

ABA问题


面试中比较容易考到CAS问题 并且一旦考到,一定会涉及ABA问题

CAS(M,A,B)

M内存 A、B两个寄存器

如果M中的值和A相同,则交换M和B的值(交换的目的是将B赋值给M,我们不关心寄存器中的值)

如果M中的值和A不相同,则无事发生,同时整个操作返回false

//伪代码
boolean CAS(address,expectValue,swapValue){
        if(&address==expectValue){
            &address=swapValue;
            return true;
        }
        return false;
    }

CAS操作主要有三个参数:要更新的内存位置、期望的值和新值。CAS操作的执行过程如下:

①首先,获取要更新的内存位置的值,记为var。
②然后,将期望值expected与var进行比较,如果两者相等,则将内存位置的值var更新为新值new。
③如果两者不相等,则说明有其他线程修改了内存位置的值var,此时CAS操作失败,需要重新尝试。

加锁是通过阻塞的方式,避免穿插

CAS是通过重试的方式,避免穿插

CAS本质是一个cpu指令,是单个指令(原子的),所以,可以用CAS完成一些操作,进一步代替加锁操作

基于CAS实现线程安全的方式,也称为”无锁编程“

优点:保证线程安全,同时避免阻塞(效率)

缺点:代码更复杂,不好理解;只能适合一些特定场景,不如加锁更普遍

ABA问题

有第三个线程穿插,使得值A->B->A

针对第一个线程,值看起来还是A,但是已经被穿插执行了

大部分情况下ABA不会出现bug(值又被改回去了),但也有一些极端情况

如何避免ABA问题出现?

让判定的数值按照一个方向增长(只是增加或者只是减少)

如果有增有减,可以引入一个额外的变量——版本号,约定每次修改时,让版本号自增,使用CAS判定时,看版本号是否变化,若无变化,则是没有线程穿插执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值