CAS 机制是什么?

#牛客AI配图神器#CAS(Compare-And-Swap)即比较并交换,是一种实现并发算法时常用到的技术,用于在多线程环境下实现无锁的同步操作。下面从基本概念、原理、Java 中的实现、优缺点等方面详细介绍 CAS 机制。

基本概念

CAS 是一种乐观锁策略,它假设在大多数情况下,多个线程不会同时修改同一个共享变量,因此不会像传统的锁机制那样在访问共享资源时直接加锁,而是在更新数据时进行检查,如果数据没有被其他线程修改,就进行更新;如果数据已经被修改,则重试或放弃操作。

原理

CAS 操作包含三个操作数:内存位置(V)、预期原值(A)和新值(B)。具体执行过程如下:

  1. 首先读取内存位置 V 处的值,将其作为预期原值 A。
  2. 在准备更新 V 处的值时,再次读取 V 处的值,检查其是否与预期原值 A 相等。
  3. 如果相等,说明在这期间没有其他线程修改过该值,就将新值 B 写入 V 处;如果不相等,说明该值已经被其他线程修改过,当前操作失败,通常需要重试整个操作。

Java 中的实现

在 Java 中,java.util.concurrent.atomic 包下提供了一系列基于 CAS 实现的原子类,例如 AtomicIntegerAtomicLong 等。以下是一个使用 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
#JAVA面经##聊聊我眼中的AI##机械人面试中的常问题##牛客创作赏金赛#
职保镖-扶你上马 文章被收录于专栏

知识分享,交天下朋友,扶你上马,送你一层,职业规划,面试指导、高薪谈判、背调辅助

全部评论

相关推荐

09-28 01:16
已编辑
门头沟学院 Java
8.21 一面1. Java 的 GC 回收机制吗?可以简单说一下。2. 你在实习阶段或者自己做项目的时候,有实际分析过线上 GC 的内存使用情况以及线程情况吗?3. 你了解 MySQL 里面的各种锁,比如表级锁、行级锁、页锁之类的吗?可以说一下这些锁的特点以及它们锁的范围。4. 什么情况下会出现锁升级呢?(MySQL 的锁升级)5. 你了解 MVCC 吗?可以简单说一下。6. 在 MySQL 里,有索引但索引失效会是什么样的问题?可以说三个情况。7. 你了解归并排序吗?可以讲一下归并排序的大致实现原理。8. 你用过 MQ 相关的吗?比如说 Kafka。9. 你们之前用 Redis 除了用分布式锁以外,还用过其他什么场景?除了布隆过滤器还有吗?10. 你对 AI 以及 AI CODING 的了解,还有对它们未来的看法是怎样的?11. 在 AI 相关,比如大数据或算法方面,你之前有过哪些经验、实践?手撕:删除倒数第k个节点最小覆盖子串8.27 二面实习深挖(30min)平时一般通过什么方式学习技术?你提到了解大模型 Agent,做过相关应用吗?或者了解过哪些 Agent 应用?你了解 AI Coding 吗?在实习中有什么 AI Coding 的实践经验?你个人对毕业以后的职业规划是怎样的无手撕;8.31收到短信挂,进人才库。 感觉二面面试官不太喜欢我9.2 捞,9.4 一面1. ConcurrentHashMap,2. synchronized和ReentrantLock3. 分布式系统注册中心是怎么做的?4. 限流算法;5. Spring循环依赖问题6. 索引类型,7. 主从复制的过程 :dump线程 io线程 sql线程8. Redis如何解决分布式下节点变化9. Redis分片,哈希槽,一个请求打过来的过程?10. 开放性问题:一个服务如果耗时增加了,如何排查;手撕:最大子数组和复原IP地址(说思路)9.11 发现又回人才池了,这次连短信都没有-------------------------------------------------------------------------------9.22 鸡架捞,进程间通信有哪些方式?用 socket 方式进行进程间通信,具体是怎么实现的?除了通过网络 socket,同一机子内部的进程进行通讯,还有别的方式吗?其转发只能通过绑定 IP 和端口吗?Linux 操作系统回写回收脏页是怎么做的?TCP 和 UDP 属于同一层协议,UDP 无法保证消息准确性,若要求在应用层用 UDP 实现一个类似 TCP 的功能,有哪些要点需要实现?在浏览器上点击一个链接,到拿到结果的过程中,会用到哪些网络协议(不限层级)?线程池有几个重要参数,分别是什么?若一个线程池尚未初始化,提交任务后直到线程池崩溃,整个过程中会依次用到哪些线程池参数?线程工厂(Thread Factory)有什么作用?你用过与 Java 命令在同一目录下的 bin 命令吗?简单说几个。       jstack jps 那些你在线上用过这些工具吗?在什么情况下使用的?你了解 LRU 数据结构吗?它是用什么数据结构组合实现的?你知道红黑树吗?java 哪些地方会用到红黑树?一个自创题,算是有向图判断是否有环?只用写伪代码基本都答的上来,题也算撕出来了,9.26 又又又又又又又又又又挂了  天呢美团大人
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务