【Java】CAS锁

news2024/9/29 15:19:20

一、什么是CAS机制(compare and swap)

1.概述

CAS的全称为Compare-And-Swap,直译就是对比交换。是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值。经过调查发现,其实现方式是基于硬件平台的汇编指令,就是说CAS是靠硬件实现的,JVM只是封装了汇编调用,那些AtomicInteger类便是使用了这些封装后的接口。

简单解释:CAS操作需要输入两个数值,一个旧值(期望操作前的值)和一个新值,在操作期间先比较下在旧值有没有发生变化,如果没有发生变化,才交换成新值,发生了变化则不交换。

2.CAS算法的作用:

解决多线程条件下使用锁造成性能损耗问题的算法,保证了原子性,这个原子操作是由CPU来完成的

3.CAS的原理:

CAS算法有三个操作数,通过内存中的值(V)、预期原始值(A)、修改后的新值(B)。

(1)如果内存中的值和预期原始值相等, 就将修改后的新值保存到内存中。

(2)如果内存中的值和预期原始值不相等,说明共享数据已经被修改,放弃已经所做的操作,然后重新执行刚才的操作,直到重试成功。

在这里插入图片描述

注意
(1)预期原始值(A)是从偏移位置读取到三级缓存中让CPU处理的值,修改后的新值是预期原始值经CPU处理暂时存储在CPU的三级缓存中的值,而内存指定偏移位置中的原始值。

(2)比较从指定偏移位置读取到缓存的值与指定内存偏移位置的值是否相等,如果相等则修改指定内存偏移位置的值,这个操作是操作系统底层汇编的一个原子指令实现的,保证了原子性。

  • JVM中CAS是通过UnSafe类来调用操作系统底层的CAS指令实现。
  • CAS基于乐观锁思想来设计的,其不会引发阻塞,synchronize会导致阻塞。
import java.util.concurrent.atomic.AtomicInteger;

public class CASDemo {
    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(2023);
        //期望时5,如果是5则改成2022
        System.out.println(atomicInteger.compareAndSet(2023, 2022) + "\t" + atomicInteger.get());
        System.out.println(atomicInteger.compareAndSet(2023, 2022) + "\t" + atomicInteger.get());
    }
}

结果

true	2022
false	2022

二、CAS和syncronized的比较

  • CAS线程不会阻塞,线程一致自旋
  • syncronized会阻塞线程,会进行线程的上下文切换,会由用户态切换到内核态,切换前需要保存用户态的上下文,而内核态恢复到用户态,又需要恢复保存的上下文,非常消耗资源。

三、CAS的缺点

(1)ABA问题

如果一个线程t1正修改共享变量的值A,但还没修改,此时另一个线程t2获取到CPU时间片,将共享变量的值A修改为B,然后又修改为A,此时线程t1检查发现共享变量的值没有发生变化,但是实际上却变化了。

解决办法

使用版本号,在变量前面追加上版本号,每次变量更新的时候把版本号加1,那么A-B-A 就会变成1A-2B-3A。从Java1.5开始JUC包里提供了一个类AtomicStampedReference来解决ABA问题。AtomicStampedReference类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前版本号是否等于预期版本号,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。

(2)CAS频繁失败导致CPU开销大

循环时间长开销会比较大:自旋重试时间,会给CPU带来非常大的执行开销

(3)只能支持一个变量的原子操作,不能保证整个代码块的原子操作

只能保证一个共享变量的原子操作,不能保证同时对多个变量的原子性操作

解决办法

从Java1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行CAS操作

四、CAS使用注意事项

(1)CAS需要和volatile配合使用

CAS只能保证变量的原子性,不能保证变量的内存可见性。CAS获取共享变量的值时,需要和volatile配合使用,来保证共享变量的可见性

(2)CAS适用于并发量不高、多核CPU的情况

CPU多核情况下可以同时执行,如果不合适就失败。而并发量过高,会导致自旋重试耗费大量的CPU资源

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

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

相关文章

测试——基本概念

概念 测试和调试有以下几点区别: 测试是测试人员进行的工作,调试是开发人员调试是发现并解决问题,测试只是发现问题测试贯穿于整个项目的生命周期,而调试主要在编码阶段 测试人员一般有如下的工作: 需求分析&#x…

Spring MVC 源码- ViewResolver 组件

ViewResolver 组件ViewResolver 组件,视图解析器,根据视图名和国际化,获得最终的视图 View 对象回顾先来回顾一下在 DispatcherServlet 中处理请求的过程中哪里使用到 ViewResolver 组件,可以回到《一个请求响应的旅行过程》中的 …

进程地址空间(虚拟地址空间)

目录 引入问题 测试代码 引入地址空间 故事1: 故事二: 解决问题 为什么有虚拟地址空间 扩展 扩展1(没有地址空间,OS如何工作) 扩展2 (代码只读深入了解) 扩展3(malloc本质…

0 初识Kotlin

0 基本介绍 相信很多开发者对Kotlin还是比较陌生的。 Kotlin是一种新型的编程语言,由JetBrains公司开发与设计,在2012年开源, 但没引起什么注意。 直到2017年google宣布将Kotlin作为Android开发的首选语言,Kotlin才开始大放异彩。…

基于MATLAB的MIMO预编码设计:优化迫零算法(附完整代码与分析)

目录 一.介绍 二. 对比本方案优化后的迫零算法与原始的迫零算法 三. 源代码 四. 运行结果及分析 4.1 天线数为8 4.2 天线数为128 一.介绍 图中“RF Chain” 全称为Radio Frequency Chain,代表射频链路。 此MIMO预编码包含了基带预编码W(改变幅度和…

NVIDIA GPU开源驱动编译学习架构分析

2022年5月,社区终于等到了这一天,NVIDIA开源了他们的LINUX GPU 内核驱动, Linux 内核总设计师 Linus Torvalds 十年前说过的一句话,大概意思是英伟达是LINUX开发者遇到的硬件厂商中最麻烦的一个,说完这句话之后&#x…

20230225英语学习

Is Your Phone Heavier When It’s Full of Data? We’ve Done the Math 从数学角度看,充满数据的手机会更重吗? Here’s a weird question: does your phone weigh more when it’s “full” than when it’s “empty”?It sounds almost ridiculou…

【unity游戏制作-mango的冒险】场景二的镜头和法球特效跟随

👨‍💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏:unity游戏制作 ⭐mango的冒险场景二——镜头和法球特效跟随⭐ 文章目录⭐mango的冒险场景二——镜…

C#的多线程、线程池和Task

线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。 线程是轻量级进程。一个使用线程的常见实例是现代操作系统中并行编程的…

如何使用Python和ftplib模块连接到FTP服务器并列出远程目录中的文件?

ftp服务可以用在以下一些使用场景: 文件共享:使用Python和FTP服务器可以轻松地搭建一个文件共享服务,使得用户可以上传和下载文件,从而促进协作和信息共享。 数据备份:FTP可以用于将数据备份到另一个服务器或云存储中…

Git ---- GitHub 操作

Git ---- GitHub 操作1. 创建远程仓库2. 远程仓库操作1. 创建爱你远程仓库别名2. 推送本地分支到远程仓库3. 克隆远程仓库到本地4. 邀请加入团队5. 拉取远程库内容3. 跨团队协作4. SSH 免密登录GitHub 网址:https://github.com/ Ps:全球最大同性交友网站…

实现弹窗功能并修改其中一个系数

把鼠标放在number-info上面,会是一个delon/chart的类库,可以在NG-ALAIN上找到阅读NG ALAIN的图表,以及number-info样式,数据文本 它拥有[title] [subtitle]两个可以是TemplateRef类型的,而template可以在里面放一些东西,比如按钮,所以可以放一个修改按钮 这里刚开始把template放…

学习 Python 之 Pygame 开发魂斗罗(三)

学习 Python 之 Pygame 开发魂斗罗(三)继续编写魂斗罗1. 角色站立2. 角色移动3. 角色跳跃4. 角色下落继续编写魂斗罗 在上次的博客学习 Python 之 Pygame 开发魂斗罗(二)中,我们完成了角色的创建和更新,现…

MySQL高级第一讲

目录 一、MySQL高级01 1.1 索引 1.1.1 索引概述 1.1.2 索引特点 1.1.3 索引结构 1.1.4 BTREE结构(B树) 1.1.5 BTREE结构(B树) 1.1.6 索引分类 1.1.7 索引语法 1.1.8 索引设计原则 1.2 视图 1.2.1 视图概述 1.2.2 创建或修改视图 1.3 存储过程和函数 1.3.1 存储过…

openresty的部署、nginx高速缓存的配置、nginx日志的可视化

文章目录一、openresty1.OpenResty简介2.OpenResty的技术3.OpenResty的优势4.openresty部署实验二、nginx配置高效缓存三、nginx日志可视化一、openresty 1.OpenResty简介 OpenResty官网 http://openresty.org/cn/ OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台&#x…

shell基础学习

文章目录查看shell解释器写hello world多命令处理执行变量常用系统变量自定义变量撤销变量静态变量变量提升为全局环境变量特殊变量$n$#$* $$?运算符:条件判断比较流程控制语句ifcasefor 循环while 循环read读取控制台输入基本语法:函数系统函数basenamedirname自定义函数shel…

FL StudioV21电脑版水果编曲音乐编辑软件

这是一款功能十分丰富和强大的音乐编辑软件,能够帮助用户进行编曲、剪辑、录音、混音等操作,让用户能够全面地调整音频。FL水果最新版是一款专业级别的音乐编曲软件,集合更多的编曲功能为一身,可以进行录音、编辑、制作、混音、调…

计算机网络(六): HTTP,HTTPS,DNS,网页解析全过程

文章目录一、HTTP头部包含的信息通用头部请求头部响应头部实体头部二、Keep-Alive和非Keep-Alive的区别三、HTTP的方法四、HTTP和HTTPS建立连接的过程4.1 HTTP4.2 HTTPS五、HTTP和HTTPS的区别六、HTTPS的加密方式七、cookie和sessionsessioncookie八、HTTP状态码状态码200&…

【微信小程序】-- WXML 模板语法 - 数据绑定(九)

💌 所属专栏:【微信小程序开发教程】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &…

DPDK系列之四DPDK整体框架分析说明

一、网络发展和DPDK 在上篇分析过网络应用对DPDK出现的影响。而具体体现在技术上,从最简单来看就是从C10K到c100K甚至更多。而相应的计算的发展也从挖掘单CPU的性能发展到了瓶颈,同样,对于网络设备也遇到了类似的问题。而目前解决问题的方法…