Java中的CAS简述

news2024/11/6 3:00:59

目录

1、CAS是什么

2、CAS的生活化例子

3、Java中的atomic包

4、unsafe类

5、CAS的缺点及解决方案

小结


1、CAS是什么

CAS(Compare and Swap)是一种并发编程中的原子操作,用于实现多线程环境下的无锁同步。它是一种乐观锁的实现方式,通过基于硬件的原子指令,同时完成“读内存,比较是否相等,修改内存”这三个步骤,本质上需要CPU指令的支持。通过比较内存中的值与预期值是否相等来决定是否进行更新。

在Java中,CAS通常使用java.util.concurrent.atomic包下的原子类来实现,例如AtomicInteger、AtomicLong、AtomicReference等。这些原子类提供了一系列的原子操作方法,保证了操作的原子性和线程安全性。

CAS操作包含三个操作数:内存位置(通常是一个变量)预期值新值

它的执行过程如下:

1. 获取当前内存位置的值(旧值)。

2. 比较内存位置的值与预期值是否相等,如果相等则执行第4步否则(不相等)执行第3步

3. 更新内存位置的值为新值,然后返回到第1步

4. CAS操作成功,更新成功;否则,返回到第1步。

CAS实现流程图:

图片来源:【Java中的CAS实现原理】_java cas原理_浪打白龙的博客-CSDN博客

2、CAS的生活化例子

例如:常见的修改登录密码操作。我们无论是在各个APP还是网站上修改密码的时候,一般都需要输入用户id、原密码和新密码等诸如此类的方式。那么在这个修改操作过程中,需要的是:数据库存储的原密码信息、用户输入的原密码、以及更新后的新密码。数据存储的原密码信息(主内存),用户输入的原密码(线程副本)。当数据库中存储的和用户输入的原密码对比相同的时候,才可以将原密码更新为新密码,否则就不能更新。

简单理解就是:线程M(工作区值为A),认为主内存V中的共享变量值是(包含)A,如果V的值是A,那么就将新值B替换V。如果不是,就不更新V的值,只要告诉我V的最新值。线程M会一直自旋操作。

3、Java中的atomic包

Java中的java.util.concurrent.atomic包提供了一组原子类,用于支持在多线程环境下进行原子操作。这些原子类提供了一些基本类型的原子操作,如整型、长整型、布尔型等,以及一些引用类型的原子操作。

以下是java.util.concurrent.atomic包中常用的原子类:

AtomicBoolean:提供了对布尔类型的原子操作,支持原子的读取和设置操作。

AtomicInteger:提供了对整型的原子操作,支持原子的读取、设置、自增、自减等操作。

AtomicLong:提供了对长整型的原子操作,支持原子的读取、设置、自增、自减等操作。

AtomicReference:提供了对引用类型的原子操作,支持原子的读取和设置操作。

AtomicIntegerArray:提供了对整型数组的原子操作,支持原子的读取、设置、自增、自减等操作。

AtomicLongArray:提供了对长整型数组的原子操作,支持原子的读取、设置、自增、自减等操作。

AtomicReferenceArray:提供了对引用类型数组的原子操作,支持原子的读取和设置操作。

这些原子类的操作都是线程安全的,可以在多线程环境下进行并发访问而不需要额外的同步措施(如锁)。它们使用了底层的硬件原子指令或其他技术来实现原子性,从而提供了高效且线程安全的操作。 通过使用atomic包中的原子类,可以简化多线程编程的复杂性,并提高程序的性能和可靠性。它们通常用于实现计数器、标志位、状态标记等在多线程环境下的共享变量。

4、unsafe类

(1)CAS的原子性靠的是底层的unsafe类,这个类中文译为“不安全的”,因此对于普通程序员来说是“有风险”的,一般应用开发者不会用到这个类。

(2)unsafe类是CAS的核心类,由于java无法直接访问底层系统,需要通过本地(native)方法访问,通过该类可以直接操作特定的内存数据。unsafe类存在于sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存,因为java中的CAS依赖于unsafe类中的方法。

(3)注意unsafe类中的所有方法都是native修饰的,也就是说unsafe类中的方法都直接调用操作系统底层资源执行相应任务,unsafe类中的native方法是调用底层原语,原语是有原子性的。

5、CAS的缺点及解决方案

ABA问题,即在操作过程中,内存位置的值可能经过多次修改后又恢复成原来的值。

解决方案:可以添加版本号作为标识,在CAS比较数据当前值和旧值的时候,也要比较版本号是否符合预期,从而对应地增加版本号。如果当前版本号和读到的版本号一致,则修改数据,版本号+1; 如果当前版本号高于读到的版本号,就操作失败。

Java提供了AtomicStampedReference和AtomicMarkableReference等类来解决ABA问题。

只能保证一个共享变量的原子操作

JDK1.5之后,新增了AtomicReference类来保证引用对象之间的原子性,可以将多个变量放到一个对象中。

循环时间长开销大,高并发多个线程同时操作的情况下,可能会导致大量线程CAS失败,CAS保持长时间自旋,加重CPU的执行负担,降低了并发能力。

解决方案: 1. 分散操作热点,使用 LongAdder 替代基础原子类 AtomicLong。2. 使用队列削峰,将发生 CAS 争用的线程加入一个队列中排队,降低 CAS 争用的激烈程度。例如JUC 中非常重要的基础类 AQS(抽象队列同步器)。

小结

总之,CAS是一种无锁同步的机制,通过比较并交换的方式来实现多线程环境下的原子操作。它避免了使用锁的开销,提供了一种高效的并发同步方式。

参考:

【精选】Java中CAS详解_java cas-CSDN博客

https://www.cnblogs.com/Shuuichi/p/10590710.html

并发编程之CAS&Atomic原子操作 - 知乎

【精选】Java多线程 (三)—— CAS机制_java中的cas机制_有你的星空的博客-CSDN博客

https://baijiahao.baidu.com/s?id=1662010083512305225&wfr=spider&for=pc

Java中的CAS_java cas用法-CSDN博客


感谢阅读,码字不易,多谢点赞!如有不当之处,欢迎反馈指出,感谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1129133.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式限流:Redis

目录 1:如何实现分布式限流 2:限流的几种类别 2.1:固定窗口限流 2.2:滑动窗口限流 2.3:漏桶限流 2.4:令牌桶限流 3:实现分布式限流:Redis 3.1:引入Redisson的依赖包 3.2:初始化Redisson 3.3:创建Redisson的限流类 1:如何实现分布式限流 1:把统计用户的使用频率等这些…

Springcloud介绍

1.基本介绍 Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring …

欧拉图和哈密顿图

欧拉图 在连通图G中,经过G的每条边一次且仅一次的通路,称为欧拉通路若欧拉通路为回路,则称为欧拉回路含有欧拉回路的图称为欧拉图有欧拉通路则G可以一笔画出有欧拉回路则G是连通的且无奇点(欧拉图无奇点) 哈密顿图 …

2023了,是时候使用pnpm了!

2023了,是时候使用pnpm了! Excerpt 2023了,是时候使用pnpm了! 什么是pnpm pnpm代表performant npm(高性能的npm),同npm和Yarn,都属于Javascript包管理安装工具,它较npm和…

树与二叉树(考研版)

文章目录 树与二叉树树的基本概念结点、树属性的描述树的性质 二叉树的概念二叉树的性质二叉树的构建二叉树的遍历先序遍历中序遍历后序遍历层次遍历 递归算法和非递归算法的转换源代码 线索二叉树二叉树的线索化线索二叉树 找前驱/后继 树和森林树的存储 树与二叉树的应用哈夫…

交换机基础(四):MSTP负载均衡配置案例

如图所示是某个企业内部核心网络的结构图,目前企业中有20个VLAN, 编号为VLAN1~VLAN20, 为了确保内部网络的可靠性,使用 了冗余链路和MSTP 协议。为了能更好地利用网络资源和带宽,现管理员希望通过配置MSTP 的负载均衡实现网络带宽…

【proteus】8086 写一个汇编程序并调试

参考书籍:微机原理与接口技术——基于8086和Proteus仿真(第3版)p103-105,p119-122. 参考程序是p70,例4-1 在上一篇的基础上: 创建项目和汇编文件 写一个汇编程序并编译 双击8086的元件图: …

2.1 向量与线性方程组

一、行图像与列图像 线性代数的中心问题是求解线性方程组。线性的意思是这些方程的未知数是一次的,即每个未知数只会乘数字,而不会出现 x x x 与 y y y 相乘的项。下面是一个由两个未知数组成的方程组: 两个方程 两个未知数 { x − 2 y 1…

Django学习笔记——文件上传(界面还怪好看得嘞)

定义文件上传函数 #文件上页面 def uploadFileIndex(request):return render(request, "uploadFile.html")#文件上传接口 def uploadFile(request):if request.method POST and request.FILES[file]:uploaded_file request.FILES[file]fs FileSystemStorage()# 选…

螺旋矩阵[中等]

优质博文:IT-BLOG-CN 一、题目 给你一个m行n列的矩阵matrix,请按照顺时针螺旋顺序,返回矩阵中的所有元素。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5] 示例 2&#xf…

vue如何使用冻结对象提升代码效率及其原理解析

先给大家伙整个实际工作中一定会碰到的问题 如下vue dome ,它的代码非常简单功能也1非常简单,就是一个按钮,点击后会显示有多少条数据 来看看源码, html部分就是一个按钮绑定了一个loadData事件,然后在p标签内展示了这个myData这个数据的长度 <template><div id&quo…

Txt病毒

一.txt病毒原理 利用翻转字符串的方法 混淆伪装 &#xff08;jpg 、doc、ppt 等&#xff09; &#xff08;1&#xff09;更改程序图标 &#xff08;2&#xff09;将程序重命名 readtxt.exe 鼠标放到 read 与 txt 中间 设置格式为 RLO // 这个“RLO”是一个转义字符&#xf…

交互式 Web 应用 0 基础入门

初探 Gradio&#xff1a;轻松构建交互式 Web 应用 文章目录 初探 Gradio&#xff1a;轻松构建交互式 Web 应用Why Gradio?安装 Gradio创建交互式界面1. gr.Interface2. gr.Blocks 强大的组件库输入输出组件控制组件布局组件 示例交互式数据可视化多组件同时&#xff08;嵌套&a…

Netty框架详解

一、Netty简介 Netty是一款基于Java NIO的网络编程、高性能、异步事件驱动的网络应用框架。它的设计目标是提供简单易用、高性能、可扩展的网络编程框架。 二、Netty主要特点 高并发&#xff1a;Netty使用异步的、非阻塞的I/O模型&#xff0c;通过事件驱动的方式处理网络操作…

回归预测 | MATLAB实现BO-LSTM贝叶斯优化长短期神经网络多输入单输出回归预测

回归预测 | MATLAB实现BO-LSTM贝叶斯优化长短期神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现BO-LSTM贝叶斯优化长短期神经网络多输入单输出回归预测效果一览基本介绍模型搭建程序设计参考资料 效果一览 基本介绍 MATLAB实现BO-LSTM贝叶斯优化长短期神经网络多输入…

潮流玩具演绎城市文化,泡泡玛特入选2023“上海礼物”

每一座城市都有其独特的文化氛围和历史背景&#xff0c;“城市礼物”承载着地域特色、文化内涵和人文精神&#xff0c;不断复制和传递着城市文化。近年来&#xff0c;上海市文旅局会同有关各方&#xff0c;从旅游商品的研发设计、品牌塑造、展售渠道等方面&#xff0c;创建“上…

【软件教程】如何用C++交叉编译出能在Android运行的ELF程序或so动态库

一、配置NDK交叉编译平台 1. 打开Android的官方ndk下载链接https://developer.android.com/ndk/downloads?hlzh-cn&#xff0c;下载windows 64位ndk环境包。 2. 解压后将具有以下文件的路径加入到系统环境变量。 3. 配置好环境变量&#xff0c;如下图所示&#xff0c;Path中存…

mysql 数据库 表结构生成word文档

1、背景 我们在做项目时&#xff0c;表设计文档都是非常重要的&#xff0c;可以让开发人员快速了解表与业务的关系、表之间的关系。 产品在不停迭代的过程中&#xff0c;表的结构也会有相应的变化&#xff0c;我们需要将变化更新的表设计文档中。以前我们是人工方式更新文档&…

C++ 虚函数详解:多态性实现原理及其在面向对象编程中的应用

在面向对象的编程中&#xff0c;多态性是一个非常重要的概念。多态性意味着在不同的上下文中使用同一对象时&#xff0c;可以产生不同的行为。C是一种面向对象的编程语言&#xff0c;在C中&#xff0c;虚函数是实现多态性的关键 什么是虚函数 虚函数是一个在基类中声明的函数&…

基于SpringBoot的时间管理系统

基于SpringBoot的时间管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 登录界面 管理员界面 用户界面 摘要 基于Spring Boot的时间管理系统是一款功能丰富…