Java多线程基础-12:详解CAS算法

CAS(CompareAndSwap)是并发编程中的一个重要概念,它在不加锁的情况下保证线程安全。CAS操作包括内存位置、期望值和新值,如果内存位置的值与期望值相等,则更新新值。它常用于实现无锁编程,如原子类(如AtomicInteger)和自旋锁。文章还讨论了CAS的ABA问题以及如何通过使用版本号来解决这个问题。

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

CAS的全称是 Compare And Swap(比较并交换),它是并发编程中的一个重要概念。本文结合Java的多线程操作来讲解CAS算法。

CAS算法的优势是可以在不加锁的情况下保证线程安全,从而减少线程之间的竞争和开销。

目录

一、CAS算法的内容

1、基本思想和步骤

2、CAS伪代码(如果把CAS想象成一个函数)

二、CAS算法的应用

1、实现原子类

*伪代码实现原子类

2、实现自旋锁

*伪代码实现自旋锁

三、CAS的ABA问题

1、ABA问题引发的BUG

2、解决ABA问题——使用版本号


一、CAS算法的内容

1、基本思想和步骤

CAS算法的基本思想是,先比较内存M中的值与寄存器A中的值(旧的预期值,expectValue)是否相等,如果相等,则将寄存器B中的值(新值,swapValue)写入内存;如果不相等,则不做任何操作。整个过程是原子的,不会被其他并发操作中断。

这里虽然涉及到内存与寄存器值的“交换”,但更多时候我们并不关心寄存器中存的值是什么,而是更关心内存中的数值(内存中存的值即变量的值)。所以这里的“交换”可以不用看成交换,直接看成是赋值操作就行,即把寄存器B中的值直接赋值到内存M中了。

CAS 操作包括三个操作数:一个内存位置(通常是共享变量)、期望的值和新值。CAS 操作的执行过程如下:

  1. 读取内存位置的当前值。
  2. 比较当前值与期望的值是否相等。
  3. 如果相等,将新值写入内存位置;否则,操作失败。

2、CAS伪代码(如果把CAS想象成一个函数

boolean CAS(address, expectValue, swapValue) {
 if (&address == expectedValue) {
   &address = swapValue;
        return true;
   }
    return false;
}

上面给出的代码只是伪代码,并不是真实的CAS代码。事实上,CAS操作是一条由CPU硬件支持的、原子的硬件指令,这一条指令就能完成上述这一段代码的功能。

“一条指令”和“一段代码”的最大区别在于原子性。上述这一段伪代码不是原子的,运行过程中可能随着线程的调度有概率产生线程安全问题;但原子的指令不会有线程安全问题。

同时,CAS也不会有内存可见性的问题,内存可见性相当于是编译器把一系列指令的进行了调整,把读内存的指令调整成读寄存器的指令。但CAS本身就是指令级别读取内存的操作,所以不会有内存可见性带来的线程不安全问题。

因此,CAS可以做到不加锁也能一定程度地保证线程安全。这样就引申出基于CAS算法的一系列操作。


二、CAS算法的应用

CAS可以用于实现无锁编程。实现原子类和实现自旋锁就是无锁编程的其中两个方式。

1、实现原子类

标准库 java.util.concurrent.atomic 包中有很多类使用了很高效的机器级指令而不是使用锁) 来保证其他操作的原子性

例如Atomiclnteger 类提供了方法 incrementAndGet、getAndIncrement 和 decrementAndGet、getAndDecrement,它们分别以原子方式将一个整数自增或自减。

        AtomicInteger num = new AtomicInteger(0);
        Thread t1 = new Thread(()->{
                //num++
                num.getAndIncrement();
                //++num
                num.incrementAndGet();
                //num--
                num.getAndDecrement();
                //--num
                num.decrementAndGet();
        });

例如,可以安全地生成数值序列,如下所示

import java.util.concurrent.atomic.Atomic
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值