【并发编程】什么是CAS?Java是如何实现CAS操作的?

news/2024/10/18 8:19:59/


目录

一.什么是CAS?

二.Java中如何实现CAS操作?


一.什么是CAS?

在Java并发编程中,CAS 代表 "Compare-And-Swap"(交换并比较),这是一种用于实现无锁编程的原子操作。CAS操作通常用于多线程环境中,以确保在没有使用传统锁的情况下,能够安全地更新共享数据。CAS是通过CPU级别的原子指令来实现的,这意味着一个CAS操作就是一个原子操作,该操作一旦开始就不能被打断,必须等待它完成。

CAS操作包含三个用到的值:

  • 内存值(V):这是要更新的变量的当前值。
  • 旧的预期值(A):这是执行CAS操作前,线程预期的内存值。
  • 要更新的新值(B):如果当前值与预期值相匹配,那么将内存值更新为这个新值。
java">boolean CAS(V, A, B)

这个操作会原子性地检查内存值是否等于旧的预期值(A),如果是,则将内存值更新为新值(B),并返回true表示操作成功。如果内存值不等于预期值,表示在CAS操作执行之前,其他线程已经修改了这个值,那么操作将不会执行更新,而是返回false。

如下图所示ACS操作再修改数据的时候,首先会将原值拿出来保存,计算修改后的值也进行保存,在真正修改之前会先取出现在目标数据的值,并且进行判断俩次取出来的值是否相同,如果相同那么就正常进行修改;如果不相同,那就说明在俩次取值的过程中,目标数据已经被其他线程修改过了,那么就继续重复上述操作,只有在原值和现在的值相同的情况下才进行更新替换。


 

在上述过程中,我们可以看出ASC操作并没有对某个变量进行加锁,它主要是通过不断的判断某个值是否已经被修改来保证数据的一致性的,这也就意味着一直有一个线程来干这件事。

使用CAS的优点包括:

  • 无锁设计:CAS操作允许无锁的线程安全编程,这可以减少线程竞争和锁的开销。
  • 性能:在某些情况下,CAS操作比使用锁具有更高的性能,特别是在高并发环境下。
  • 避免死锁:由于没有使用锁,因此使用CAS可以避免死锁问题。

然而,CAS也有其缺点,比如:

  • ABA问题:由于CAS检查的是值而不是内存地址,如果一个值在被读取和比较期间被修改并又恢复了原值(即发生了ABA情况),CAS操作可能会错误地认为值没有变化。
  • 循环延迟:在高竞争环境下,CAS操作可能会导致线程不断自旋尝试更新值,这可能导致CPU资源的浪费。

二.Java中如何实现CAS操作?

在Java中我们可以通过UnSafe这个类来实现CAS操作,该类位于sun.misc包下。

Unsafe类提供了compareAndSwapObjectcompareAndSwapIntcompareAndSwapLong方法来实现的对Object、int、long类型的 CAS 操作

java">/*** 以原子方式更新字段的值* @param o        要操作的对象* @param offset   对象字段的内存偏移量* @param expected 期望的旧值* @param x        要设置的新值* @return 如果值被成功更新,则返回 true;否则返回 false*/ 
public final boolean compareAndSwapObject(Object o, long offset,Object expected,Object x) {return theInternalUnsafe.compareAndSetReference(o, offset, expected, x);
}public final boolean compareAndSwapInt(Object o, long offset,int expected,int x) {return theInternalUnsafe.compareAndSetInt(o, offset, expected, x);
}public final boolean compareAndSwapLong(Object o, long offset,long expected,long x) {return theInternalUnsafe.compareAndSetLong(o, offset, expected, x);
}



 本次的分享就到此为止了,希望我的分享能给您带来帮助,创作不易也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见


http://www.ppmy.cn/news/1512378.html

相关文章

【IDEA】idea配置服务器没有tomcat

IntelliJ IDEA 本身并不包含 Tomcat 服务器。 详细解释: IntelliJ IDEA 是一个集成开发环境 (IDE),为软件开发提供各种工具和功能。它专注于代码编辑、调试、代码重构和版本控制等任务。Tomcat 是一个 Java Servlet 容器和 Web 服务器,用于…

已解决:java.lang.ClassNotFoundException: com.mongodb.test.test 异常的正确解决方法,亲测有效!!!

1. 问题描述 java.lang.ClassNotFoundException 是 Java 程序在运行时找不到指定类时抛出的异常。在这类错误中,错误信息 com.mongodb.test.test 指示 Java 虚拟机 (JVM) 无法找到该类。 通常,这种错误发生在以下情况: 类路径配置错误&…

银行总分支文件分发系统:在安全与效率之间找到平衡

银行的组织结构通常根据其规模、业务范围和地域分布而有所不同,但一般会包括以下几个层级:总行-区域总部或分行-分行-支行-业务中心或服务中心-国际分支机构-附属机构或子公司。 在日常中,存在总分支文件分发的业务场景,文件类型通…

ffmpeg快速切割视频

如果有对一个很大的视频进行切割(分割)的需求,用专业的剪辑软件肯定是很慢的,而且编码、分辨率等也不能百分百保持不变,这时利用命令行调用ffmpeg就是一个很方便地选择。 命令 ffmpeg -i 待处理.mp4 -ss 00:00:00 -t 00:09:00 输出.mp4 注…

项目中如何引入Iconfont-图标库,并解决彩色图标显示黑白的问题

iconfont-阿里巴巴矢量图标库 首先附上阿里巴巴矢量图标库 找到想要的图标之后,点击购物车按钮,可以将选中的素材添加到购物车中 然后点击顶部的购物车,打开侧边栏,点击添加至项目,输入项目名后确定 然后在我的项目…

Redis7基础篇(九)

springboot集成redis 目录 springboot集成redis 总体概述 java连接redis常见问题 集成jedis 集成lettuce 集成redistemplate 连接单机 ​编辑​编辑​编辑redis集群 总体概述 java要想连接mysql的话需要jdbc java想要连接redis也需要中间件 jedis是第一代 lettuce第…

使用Linux Systemd部署DotNet Quartz.Net定时任务

开发环境 Windows 10 WSL2Ubuntu 22.04DotNet 6Quartz.Net 代码实战 新建dotnet项目,添加引用Quartz.net包 入口程序: static void Main(string[] args){IConfiguration configuration new ConfigurationBuilder().SetBasePath(Directory.GetCurren…

Nginx源码安装与进阶负载均衡

目录 一 web服务介绍 二 Nginx介绍与源码安装 2.1 nginx源码安装 2.2 平滑升级和回滚 三 配置文件详解 3.1 配置文件说明 3.2 全局配置与http模块 3.3 root与alias 3.4 location的介绍 3.5 账户认证 四 高级配置 4.1 nginx 压缩功能 4.2 变量介绍 五 nginx反向代…