CAS 机制是什么?
#牛客AI配图神器#CAS(Compare-And-Swap)即比较并交换,是一种实现并发算法时常用到的技术,用于在多线程环境下实现无锁的同步操作。下面从基本概念、原理、Java 中的实现、优缺点等方面详细介绍 CAS 机制。
基本概念
CAS 是一种乐观锁策略,它假设在大多数情况下,多个线程不会同时修改同一个共享变量,因此不会像传统的锁机制那样在访问共享资源时直接加锁,而是在更新数据时进行检查,如果数据没有被其他线程修改,就进行更新;如果数据已经被修改,则重试或放弃操作。
原理
CAS 操作包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。具体执行过程如下:
- 首先读取内存位置 V 处的值,将其作为预期原值 A。
- 在准备更新 V 处的值时,再次读取 V 处的值,检查其是否与预期原值 A 相等。
- 如果相等,说明在这期间没有其他线程修改过该值,就将新值 B 写入 V 处;如果不相等,说明该值已经被其他线程修改过,当前操作失败,通常需要重试整个操作。
Java 中的实现
在 Java 中,java.util.concurrent.atomic
包下提供了一系列基于 CAS 实现的原子类,例如 AtomicInteger
、AtomicLong
等。以下是一个使用 AtomicInteger
的示例:
import java.util.concurrent.atomic.AtomicInteger; public class CASExample { public static void main(String[] args) { // 创建一个 AtomicInteger 对象,初始值为 10 AtomicInteger atomicInteger = new AtomicInteger(10); // 预期原值 int expectedValue = 10; // 新值 int newValue = 20; // 调用 compareAndSet 方法进行 CAS 操作 boolean result = atomicInteger.compareAndSet(expectedValue, newValue); if (result) { System.out.println("CAS 操作成功,新值为: " + atomicInteger.get()); } else { System.out.println("CAS 操作失败,当前值为: " + atomicInteger.get()); } } }
在上述代码中,compareAndSet
方法就是一个典型的 CAS 操作。它会先检查 atomicInteger
的当前值是否等于预期原值 expectedValue
,如果相等,则将其更新为新值 newValue
,并返回 true
;否则返回 false
。
优缺点
优点
- 性能高:相比于传统的锁机制(如
synchronized
),CAS 操作避免了线程的阻塞和唤醒过程,减少了上下文切换的开销,因此在竞争不激烈的情况下,性能更高。 - 无锁化:CAS 是一种无锁算法,不会产生死锁问题,因为它不需要像传统锁那样对资源进行独占。
缺点
- ABA 问题:如果一个值从 A 变为 B,再从 B 变回 A,CAS 操作会认为这个值没有发生变化,但实际上它已经经历了一些中间状态。在某些场景下,这种情况可能会导致问题。Java 中可以使用
AtomicStampedReference
类来解决 ABA 问题。 - 自旋开销大:在竞争激烈的情况下,CAS 操作可能会多次失败并不断重试,这会消耗大量的 CPU 资源,导致性能下降。
- 只能保证一个共享变量的原子操作:CAS 只能保证对一个共享变量的原子操作,如果需要对多个共享变量进行原子操作,CAS 就无能为力了。可以考虑使用
AtomicReference
来将多个变量封装成一个对象进行操作。JAVA
职保镖-扶你上马 文章被收录于专栏
知识分享,交天下朋友,扶你上马,送你一层,职业规划,面试指导、高薪谈判、背调辅助