当前位置: 首页 > news >正文

CAS 详解

目录

Java 中 CAS 是如何实现的?

CAS 算法存在哪些问题?

ABA 问题

循环时间长开销大

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


Java 中 CAS 是如何实现的?

在 Java 中,实现 CAS(Compare-And-Swap, 比较并交换)操作的一个关键类是Unsafe。

Unsafe类位于sun.misc包下,是一个提供低级别、不安全操作的类。由于其强大的功能和潜在的危险性,它通常用于 JVM 内部或一些需要极高性能和底层访问的库中,而不推荐普通开发者在应用程序中使用。

sun.misc包下的Unsafe类提供了compareAndSwapObject、compareAndSwapInt、compareAndSwapLong方法来实现的对Object、int、long类型的 CAS 操作:

    /*** 以原子方式更新对象字段的值。*/boolean compareAndSwapObject(Object o, long offset, Object expected, Object x);/*** 以原子方式更新 int 类型的对象字段的值。*/boolean compareAndSwapInt(Object o, long offset, int expected, int x);/*** 以原子方式更新 long 类型的对象字段的值。*/boolean compareAndSwapLong(Object o, long offset, long expected, long x);
    @ForceInlinepublic final boolean compareAndSwapObject(Object o, long offset,Object expected,Object x) {return theInternalUnsafe.compareAndSetReference(o, offset, expected, x);}/*** Atomically updates Java variable to {@code x} if it is currently* holding {@code expected}.** <p>This operation has memory semantics of a {@code volatile} read* and write.  Corresponds to C11 atomic_compare_exchange_strong.** @return {@code true} if successful*/@ForceInlinepublic final boolean compareAndSwapInt(Object o, long offset,int expected,int x) {return theInternalUnsafe.compareAndSetInt(o, offset, expected, x);}/*** Atomically updates Java variable to {@code x} if it is currently* holding {@code expected}.** <p>This operation has memory semantics of a {@code volatile} read* and write.  Corresponds to C11 atomic_compare_exchange_strong.** @return {@code true} if successful*/@ForceInlinepublic final boolean compareAndSwapLong(Object o, long offset,long expected,long x) {return theInternalUnsafe.compareAndSetLong(o, offset, expected, x);}

Unsafe类中的 CAS 方法是native方法。native关键字表明这些方法是用本地代码(通常是 C 或 C++)实现的,而不是用 Java 实现的。这些方法直接调用底层的硬件指令来实现原子操作。也就是说,Java 语言并没有直接用 Java 实现 CAS。

更准确点来说,Java 中 CAS 是 C++ 内联汇编的形式实现的,通过 JNI(Java Native Interface) 调用。因此,CAS 的具体实现与操作系统以及 CPU 密切相关。 

Atomic 类依赖于 CAS 乐观锁来保证其方法的原子性,而不需要使用传统的锁机制(如 synchronized 块或 ReentrantLock)。

AtomicInteger是 Java 的原子类之一,主要用于对 int 类型的变量进行原子操作,它利用Unsafe类提供的低级别原子操作方法实现无锁的线程安全性。

AtomicInteger核心源码如下:

// 原子地获取并增加整数值
public final int getAndAddInt(Object o, long offset, int delta) {int v;do {// 以 volatile 方式获取对象 o 在内存偏移量 offset 处的整数值v = getIntVolatile(o, offset);} while (!compareAndSwapInt(o, offset, v, v + delta));// 返回旧值return v;
}

 可以看到,getAndAddInt 使用了 do-while 循环:在compareAndSwapInt操作失败时,会不断重试直到成功。也就是说,getAndAddInt方法会通过 compareAndSwapInt 方法来尝试更新 value 的值,如果更新失败(当前值在此期间被其他线程修改),它会重新获取当前值并再次尝试更新,直到操作成功。 由于 CAS 操作可能会因为并发冲突而失败,因此通常会与while循环搭配使用,在失败后不断重试,直到操作成功。这就是 自旋锁机制 。

CAS 算法存在哪些问题?

ABA 问题是 CAS 算法最常见的问题。

ABA 问题

如果一个变量 V 初次读取的时候是 A 值,并且在准备赋值的时候检查到它仍然是 A 值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回 A,那 CAS 操作就会误认为它从来没有被修改过。这个问题被称为 CAS 操作的 "ABA"问题。 ABA 问题的解决思路是在变量前面追加上版本号或者时间戳。JDK 1.5 以后的 AtomicStampedReference 类就是用来解决 ABA 问题的,其中的 compareAndSet() 方法就是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。

    /*** Atomically sets the value of both the reference and stamp* to the given update values if the* current reference is {@code ==} to the expected reference* and the current stamp is equal to the expected stamp.** @param expectedReference the expected value of the reference* @param newReference the new value for the reference* @param expectedStamp the expected value of the stamp* @param newStamp the new value for the stamp* @return {@code true} if successful*/public boolean compareAndSet(V   expectedReference,V   newReference,int expectedStamp,int newStamp) {Pair<V> current = pair;returnexpectedReference == current.reference &&expectedStamp == current.stamp &&((newReference == current.reference &&newStamp == current.stamp) ||casPair(current, Pair.of(newReference, newStamp)));}

 

循环时间长开销大

CAS 经常会用到自旋操作来进行重试,也就是不成功就一直循环执行直到成功。如果长时间不成功,会给 CPU 带来非常大的执行开销。

如果 JVM 能够支持处理器提供的pause指令,那么自旋操作的效率将有所提升。pause指令有两个重要作用

  1. 延迟流水线执行指令:pause指令可以延迟指令的执行,从而减少 CPU 的资源消耗。具体的延迟时间取决于处理器的实现版本,在某些处理器上,延迟时间可能为零。
  2. 避免内存顺序冲突:在退出循环时,pause指令可以避免由于内存顺序冲突而导致的 CPU 流水线被清空,从而提高 CPU 的执行效率。

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

CAS 操作仅能对单个共享变量有效。当需要操作多个共享变量时,CAS 就显得无能为力。不过,从 JDK 1.5 开始,Java 提供了AtomicReference类,这使得我们能够保证引用对象之间的原子性。通过将多个变量封装在一个对象中,我们可以使用AtomicReference来执行 CAS 操作。

相关文章:

CAS 详解

目录 Java 中 CAS 是如何实现的? CAS 算法存在哪些问题? ABA 问题 循环时间长开销大 只能保证一个共享变量的原子操作 Java 中 CAS 是如何实现的? 在 Java 中&#xff0c;实现 CAS&#xff08;Compare-And-Swap, 比较并交换&#xff09;操作的一个关键类是Unsafe。 Un…...

AI大模型那么火,教你一键Modelarts玩转开源LlaMA(羊驼)大模型

近日&#xff0c; LlaMA(羊驼) 这个大模型再次冲上热搜&#xff01; LLaMA&#xff08;Large Language Model Meta AI&#xff09;&#xff0c;由 Meta AI 发布的一个开放且高效的大型基础语言模型&#xff0c;共有 7B、13B、33B、65B&#xff08;650 亿&#xff09;四种版本。…...

Spring AI Alibaba: 支持国产大模型的Spring ai框架

Spring AI &#xff1a;java做ai应用的最好选择 过去&#xff0c;Java在AI应用开发方面缺乏一个高效且易于集成的框架&#xff0c;这限制了开发者快速构建和部署智能应用程序的能力。 Spring AI正是为解决这一问题而生&#xff0c;它提供了一套统一的接口&#xff0c;使得AI功…...

ChatGPT4o、o1 谁才是最佳大模型?

如何选择合适的 ChatGPT 模型&#xff1f;OpenAI 更新细节与 GPTs 的深入解析 随着人工智能的发展&#xff0c;ChatGPT 已成为众多用户的强大助手&#xff0c;广泛应用于写作、编程、学习和商业等多个领域。然而&#xff0c;面对 OpenAI 提供的众多模型&#xff08;如 GPT-4、…...

[笔记] 关于CreateProcessWithLogonW函数创建进程

函数介绍 https://learn.microsoft.com/zh-cn/windows/win32/api/winbase/nf-winbase-createprocesswithlogonw BOOL CreateProcessWithLogonW([in] LPCWSTR lpUsername,[in, optional] LPCWSTR lpDomain,[in] …...

Ubuntu的Qt编译环境配置

1、找不到C和C编译器 利用run文件安装QT6.8.0和QT5.12.2版本后&#xff0c;打开QtCreator时&#xff0c;找不到编译器。 可在终端中查找gcc和g版本&#xff0c;如果没有就安装。 gcc --version g --version 如果没有就安装&#xff1a; sudo apt-get install gcc sudo apt-…...

12 django管理系统 - 注册与登录 - 登录

为了演示方便&#xff0c;我就直接使用models里的Admin来演示&#xff0c;不再创建用户模型了。 ok&#xff0c;先做基础配置 首先是在base.html中&#xff0c;新增登录和注册的入口 <ul class"nav navbar-nav navbar-right"><li><a href"/ac…...

2020年计算机网络408真题解析

第一题&#xff1a; 解析&#xff1a;OSI参考模型网络协议的三要素 网络协议的三要素&#xff1a;语法 &#xff0c;语义&#xff0c;同步&#xff08;时序&#xff09; 语法&#xff1a;定义收发双方所交换信息的格式 语法&#xff1a;定义收发双方所要完成的操作 网页的加载 …...

速盾:cdn高防服务器防火墙的特性是什么?

CDN高防服务器防火墙是一种专门为互联网应用提供安全防护的网络安全设备。它采用先进的技术和算法&#xff0c;通过对网络流量进行过滤和检测&#xff0c;以防止恶意攻击和非法访问&#xff0c;保障网络服务的可用性和安全性。CDN高防服务器防火墙的特性主要包括以下几个方面&a…...

小程序分包和预加载

一、目的 分包的目的&#xff1a; 提升小程序的首屏加载速度&#xff0c;其原理和PC端网页的路由懒加载非常类似。即当我们第一个打开一个小程序的时候&#xff0c;只加载主包以及一些公共的资源&#xff0c;当调到某个页面的时候&#xff0c;在加载该页面所在的分包&#xf…...

【MATLAB 串口调试+虚拟串口测试】

文章目录 前言一、matlab 串口二、测试串口1.从系统中获取串口号2.避免串口打开被占用3. 安装虚拟串口4. 打开串口助手和MATALB 进行测试 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 项目需要&#xff1a; 提示&#xff1a;以下是本篇文章正文…...

mac 安装最新版nginx

1. clone最新版本源代码&#xff1a; git clone https://github.com/nginx/nginx.git 2. 下载PCRE 没有PCRE那我们就下&#xff0c;下载地址&#xff1a;https://sourceforge.net/projects/pcre/files/pcre/&#xff0c;笔者下载的pcre-8.45.zip&#xff0c;下载之后解压到ngi…...

极氪汽车困局:营销频繁车、产品力不足

“ 极氪汽车的“车上吃火锅”营销活动虽登上热搜&#xff0c;但因频繁忽视老用户和产品力不足的争议&#xff0c;并未赢得消费者好感&#xff0c;反而加剧负面印象。 ” 科技新知 原创 作者丨颜瞾 编辑丨蕨影 近日&#xff0c;背靠吉利集团的极氪…...

Icecream 与 Python 日志库及性能分析整合指南

简介 Icecream 是一个用于简化 Python 调试过程的库&#xff0c;它允许开发者轻松打印变量名和它们的值。Python 的 logging 库则提供了一个强大的日志记录系统&#xff0c;用于跟踪应用程序的运行情况。而性能分析则是评估代码执行效率的重要手段。本指南将介绍如何将 Icecre…...

请解读下面的程序:pat =re.compile(r‘\d+‘)res = pat.search(‘www.ddd996.com‘)res.group()

请解读下面的程序&#xff1a; pat re.compile(r\d) res pat.search(www.ddd996.com) res.group() 这段程序使用了正则表达式模块re来搜索字符串中的数字。首先&#xff0c;通过re.compile函数创建了一个正则表达式对象pat&#xff0c;该正则表达式是r\d&#xff0c;意味着匹…...

Fibonacci任意一位的值得算法

csDP写法 using System; class Program {static void Main(string[] args){Console.WriteLine("请输入一个非负整数&#xff1a;");// 读取用户输入while(true){string input Console.ReadLine();int n Convert.ToInt32(input);if (n < 0){Console.WriteLine(&…...

gbn,sr和tcp的区别

这是关于三种不同协议&#xff08;GBN、SR、TCP&#xff09;处理传输时序和丢包的行为比较。我们可以分别填充并解释它们的处理机制&#xff1a; GBN&#xff08;Go-Back-N&#xff09;协议&#xff1a; 类型发送方的计时器保存的是啥接收方收到失序的分组怎么办超时的时候发…...

FastGPT本地开发 之 通过Navicat管理MongoDB、PostgreSQL数据库

1. 背景 前期已经完成FastGPT的本地化部署工作&#xff0c;通过Docker启动FastGPT的相关容器即可运行。&#xff08;共6个容器&#xff09; 2.本地化开发 2.1 前置依赖 2.2 源码拉取 git clone gitgithub.com:labring/FastGPT.git2.3 数据库管理 本地化运行的FastGPT使用…...

hardhat部署智能合约

Hardhat安装 安装node 可以使用 nvm 安装node GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions 安装Hardhat 打开命令行工具&#xff0c;输入&#xff1a; mkdir hardhat-demo cd hardhat-demo npm i…...

界面控件DevExtreme中文教程 - 如何与Amazon S3和Azure Blob存储集成?

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序。从Angular和Reac&#xff0c…...

【ERROR】ubuntu source: not found

Ubuntu 24.04.1 LTS系统设置环境变量&#xff0c;执行 source ~/.bashrc出现错误&#xff1a; source command not found 解决方案&#xff1a;不需要处理( echo 以下你的环境变量&#xff0c;发现是生效的)&#xff0c;ubantu系统 中 /bin/sh 通常链接到 dash&#xff0c;这…...

聚焦IOC容器刷新环节postProcessBeanFactory(BeanFactory后置处理)专项

目录 一、IOC容器的刷新环节快速回顾 二、postProcessBeanFactory源码展示分析 &#xff08;一&#xff09;模版方法postProcessBeanFactory &#xff08;二&#xff09;AnnotationConfigServletWebServerApplicationContext 调用父类的 postProcessBeanFactory 包扫描 …...

配置nginx服务通过ip访问多网站

过程概要 1.前提配置 关防火墙 关selinux 2.安装web服务程序nginx 3.查看nginx是否开启 4.为当前主机添加多地址&#xff08;ip a&#xff09; 5.自定义nginx配置文件通过多地址区分多网站 /etc/nginx/conf.d/test_ip.conf server { #标记为一个虚拟主机 } 6.根据配置…...

银河麒麟V10设置QT开发程序开机自启动

1、切换root用户: su root 2、进入/etc/xdg/autostart目录&#xff1a; cd /etc/xdg/autostart 3、创建一个test.desktop文件&#xff0c;文件名不一定命名为test&#xff0c;可以自己随意命名&#xff1a; touch test.desktop 4、完善test.desktop文件内容&#xff1a; …...

RabbitMQ高级特性详解

前言 RabbitMQ是一款广泛使用的开源消息队列软件&#xff0c;它基于AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;标准实现。本文将带你深入了解RabbitMQ的一些高级特性&#xff0c;包括消息确认、死信队列、延迟队列、事务处理以及消息分发策略等&#xff…...

提升泛化能力的前沿方法:多任务学习在机器学习中的应用与实践

提升泛化能力的前沿方法&#xff1a;多任务学习在机器学习中的应用与实践 &#x1f4cb; 目录 &#x1f9e9; 多任务学习的概念与动机&#x1f310; 多任务学习在自然语言处理中的应用案例&#x1f5bc;️ 多任务学习在计算机视觉中的应用案例⚙️ 项目实践&#xff1a;实现多…...

【小白学机器学习16】 概率论的世界观2

目录 一 从正态分布说起 1.1 正态分布是自然分布&#xff0c;是客观 1.2 万物不齐 1.3 中庸 1.4 动态平衡 正态分布&#xff0c;概率论都是一种世界观 一 从正态分布说起 1.1 正态分布是自然分布&#xff0c;是客观 世界是客观的&#xff0c;是不以人们的意志想法为转…...

洛谷 P9868 [NOIP2023] 词典

好久不写博客了&#xff0c;今天来水一篇 原题链接 初看此题在洛谷上的定位是黄题&#xff0c;实际上也并不是很简单。 其实主要就用到了贪心的思想&#xff0c;先说一下我在做题的时候是怎么想的吧。 先看了部分分&#xff0c;10分是很好拿的&#xff0c;再就分析题意&…...

跨浏览器免费书签管理系统

随着互联网信息的爆炸式增长&#xff0c;如何有效管理我们日常浏览中发现的重要网页&#xff0c;成为了每个重度互联网用户的需求。一个跨平台的书签管理网站能够帮助用户在不同设备之间无缝同步和管理书签。本文将分享如何使用 Python 和 SQLite 构建一个简单、易于维护的跨平…...

导出Excel的常用方法:从前端到后端的全面指南

导出Excel的常用方法&#xff1a;从前端到后端的全面指南 在现代Web应用中&#xff0c;导出数据为Excel文件是一个常见需求。无论是为了数据分析、记录保存还是简单的数据共享&#xff0c;Excel文件都因其广泛的兼容性和易用性而成为首选格式之一。本文将介绍几种常用的Excel导…...