CAS(多线程)

本文介绍了CAS(CompareandSwap)在多线程编程中的重要性,探讨了其工作原理、优点(如原子性)以及常见的ABA问题。同时,指出了CAS的局限性,如循环时间长和对单个共享变量的限制,并举例了CAS自旋锁的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CAS概念

CAS(Compare and Swap)是一种多线程编程中常用的原子操作,它可以在多线程并发访问的情况下,保证数据的完整性和一致性。CAS的主要操作包括比较和替换,它会先比较内存中的某个位置的值是否等于预期值,如果是,则将该位置的值替换为新值;否则,什么都不做。这种操作可以确保在多线程并发访问的情况下,不会出现数据竞争和数据不一致的情况。

主要是通过处理器的指令来保证操作的原子性,它包含三个操作数:

  1. 变量内存地址,V表示
  2. 旧的预期值,A表示
  3. 准备设置的新值,B表示

当执行CAS指令时,只有当V等于A时,才会用B去更新V的值,否则就不会执行更新操作。

CAS缺点

ABA问题:ABA的问题指的是在CAS更新的过程中,当读取到的值是A,然后准备赋值的时候仍然是A,但是实际上有可能A的值被改成了B,然后又被改回了A,这个CAS更新的漏洞就叫做ABA。只是ABA的问题大部分场景下都不影响并发的最终效果。

Java中有AtomicStampedReference来解决这个问题,他加入了预期标志和更新后标志两个字段,更新时不光检查值,还要检查当前的标志是否等于预期标志,全部相等的话才会更新。(即类似检查版本)

循环时间长开销大:自旋CAS的方式如果长时间不成功,会给CPU带来很大的开销。

只能保证一个共享变量的原子操作:只对一个共享变量操作可以保证原子性,但是多个则不行,多个可以通过AtomicReference来处理或者使用锁synchronized实现

CAS自旋锁

CAS自旋锁的实现是基于比较交换算法实现,通过修改共享区域的值直到修改成功为止。

CAS自旋锁demo

import java.util.concurrent.atomic.AtomicInteger;

public class SpinLock {
	//AtomicInteger线程安全
    private AtomicInteger state = new AtomicInteger(0);

    public void lock() {
        //若无占用(为0)则占用锁(0->1),若占用则自旋等待
        while (!state.compareAndSet(0, 1)) {
            //自旋
            System.out.println("自旋等待");
        }
		
		//占用成功,处理逻辑代码
		//unlock();
    }

    public void unlock() {
        state.set(0);
    }
}

可以参考这位博主写的 (多线程)CAS ,我这边是比较简单的介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谦风(Java)

一起学习,一起进步(✪ω✪)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值