[JAVAEE] 面试题(二) - CAS 和 原子类

目录

一. CAS的实现原理

1.1 伪代码分析

1.2 底层实现 

二. CAS 操作示例

三. ABA问题

四. 原子类

4.1 使用原子类的目的

4.2 原子类的使用示例

五. 总结


一. CAS的实现原理

CAS(compare and swap 比较和交换)是一种用于实现无锁并发的技术.

1.1 伪代码分析

    // 伪代码boolean CAS(address, expectValue, swapValue) {if (&address == expectValue) {&address = swapValue;return true;}return false;}

&address: 需要修改的值.

expectValue: 预期的值.

swapValue: 新值, 需要赋值给&address的值.

核心思想: 比较当前需要修改的值和预期的值是否相同, 如果相同, 就用新值替换需要修改的值.

1.2 底层实现 

CAS无锁并发技术底层是靠C语言依赖的操作系统的原子操作来实现原子性的. 即在这个过程中不会被其他线程打断(CAS可以理解为是一个赋值操作, 这是原子性的, 不会产生线程安全问题).


二. CAS 操作示例

假设有一个整数变量count, 初始值为0, 现在有A, B两个线程同时对count进行+1操作.(使用CAS无锁并发技术)

1. 线程A读取变量count的值, 得到0.

2. 线程B读取变量count的值, 得到0.

3. 线程A将变量count的值与预期的值0进行比较, 相等, 将count的值增加为1.

4. 线程B将变量count的值与预期的值0进行比较, 不相等(count的值已经被线程A增加为1), 则重试.

5. 线程B重新读取变量count的值, 得到1.

6. 线程B将变量count的值与预期的值1进行比较, 相等, 将count的值增加为2.

最终, count的值为2.


三. ABA问题

假设有两个线程, 线程1使用CAS技术将val的值从A修改成B, 又把val的值从B修改成A. 线程2通过CAS技术判断线程1没有对val的值进行修改, 于是线程2再次修改val的值(实际上不需要修改). 这就是 ABA 问题.

解决:

在CAS操作的时候对val加版本号.

A 1.0

B 2.0

A 3.0

java中的 AtomicStampedReference类 解决了ABA问题.

四. 原子类

java中的原子类在 java.util.concurrent.atomic 包中.

4.1 使用原子类的目的

为了不加锁, 提高程序运行效率.

4.2 原子类的使用示例

实现一个无锁的计数器.

    static AtomicInteger count = new AtomicInteger();public static void main(String[] args) throws InterruptedException{Thread t1 = new Thread(() -> {for (int i = 0; i < 50000; i++) {count.getAndIncrement();}});Thread t2 = new Thread(() -> {for (int i = 0; i < 50000; i++) {count.getAndIncrement();}});t1.start();t2.start();t1.join();t2.join();System.out.println(count.get());}


五. 总结

1. CAS(compare and swap) 是一种无锁并发技术.

2. CAS的伪代码分析: 将需要修改的值和预期的值进行比较, 如果相等, 就用新值替换需要修改的值.

3. CAS的底层实现: CAS底层是靠C语言依赖的操作系统的原子操作来实现的原子性,(本质上是赋值操作, 是原子性的, 是线程安全的.)

4. ABA问题, 解决(对CAS操作需要修改的值加版本号).

5. 使用原子类的目的.(为了避免加锁操作, 提高程序运行效率).

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

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

相关文章

高职院校软件技术专业群的建设方案

一、引言 在数字化时代&#xff0c;软件技术已成为信息技术的核心驱动力&#xff0c;它不仅深刻地改变了人们的生产和生活方式&#xff0c;还成为了推动产业升级和促进经济高质量发展的关键引擎。随着全球数字化转型的加速&#xff0c;软件技术的重要性日益凸显&#xff0c;它…

不适合的学习方法

文章目录 不适合的学习方法1. 纯粹死记硬背2. 过度依赖单一资料3. 线性学习4. 被动学习5. 一次性学习6. 忽视实践7. 缺乏目标导向8. 过度依赖技术9. 忽视个人学习风格10. 过于频繁的切换 结论 以下是关于不适合的学习方法的更详细描述&#xff0c;包括额外的内容和相关公式&…

Rust精简核心笔记:第二波,语法精髓部分解锁

前面介绍了Rust精简比较第一波 Rust精简核心笔记&#xff1a;第一波&#xff0c;深入浅出语法精华-CSDN博客 把第二波整理如下&#xff0c;通过三波会把全部Rust核心、实用、最简练的语法整理出来&#xff0c;最高效掌握Rust。 Rust精简笔记(二) Rust核心笔记第二波总结整理&am…

CST软件如何理解Axial Ratio轴比

这个问题很多用户问&#xff0c;所以解答一下。 之前写过两个偏振片的案例&#xff0c;一个从S参数看轴比&#xff0c;另一个从远场结果中优化轴比。 下面我们分析一下电磁波的轴比。首先&#xff0c;轴比AR最普通的定义就是椭圆极化长短轴的比&#xff1a; 定义1&#xff1…

高等数学 6.2 定积分在几何学上的应用

文章目录 一、平面图形的面积1.直角坐标情形2.极坐标情形 二、体积1.旋转体体积2.平行截面面积为已知的立体的体积 三、平面曲线的弧长 一、平面图形的面积 1.直角坐标情形 我们已经知道&#xff0c;由曲线 y f ( x ) ( f ( x ) ⩾ 0 ) y f(x) (f(x) \geqslant 0) yf(x)(f…

Nginx 实现动态封禁IP,详细教程来了

Nginx 实现动态封禁IP&#xff0c;详细教程来了 需求环境准备设计方案在操作系统层面&#xff0c;配置 iptables&#xff0c;来拦截指定 IP 的网络请求在 Web 服务器层面&#xff0c;通过 Nginx 自身的 deny 选项或者 lua 插件配置 IP 黑名单在应用层面&#xff0c;在处理请求之…

SAP(PP生产制造)拆解工单业务处理

1、BOM维护 要拆解的成品或半成品要和原成品、半成品BOM一致 2、创建拆解工单 CO01选择拆解工单的类型&#xff0c;以及填写拆解的物料和拆解工厂 维护工单组件 注意&#xff1a; 1、拆解入库组件的数量需要维护为负数 2、拆解工单投料组件数量维护为正数 3、拆解工单收发…

【已解决】cra 配置路径别名 @ 后,出现 ts 报错:找不到模块“@/App”或其相应的类型声明。ts(2307)

cra 配置路径别名 后&#xff0c;出现 ts 报错&#xff1a;找不到模块“/App”或其相应的类型声明。ts(2307) 然后可以在 tsconfig.json 中配置 baseUrl 和 paths &#xff1a; {"compilerOptions": {"target": "es5","lib": [&quo…

定制化视频生成新模范!零样本主体驱动,精确运动控制!复旦阿里等发布DreamVideo-2

文章链接&#xff1a;https://arxiv.org/pdf/2410.13830 项目链接&#xff1a;https://dreamvideo2.github.io/ 亮点直击 DreamVideo-2&#xff0c;首个无需微调&#xff0c;同时支持主体定制和运动控制的零样本视频定制框架&#xff0c;能够通过设计的参考注意力学习主体外观&…

mockito+junit完成单元测试

一&#xff1a;单元测试的特点 配合断言使用&#xff08;可以杜绝System.out&#xff09;可以重复执行不依赖环境不会对数据产生影响spring的上下文环境不是必须的一般都需要配合mock类框架来实现 二&#xff1a;常用的mock类框架 mockito 官网&#xff1a;Mockito framew…

【LeetCode:153. 寻找旋转排序数组中的最小值 + 二分】

在这里插入代码片 &#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕…

【Python系列】poetry安装与使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

linux之网络子系统- TCP连接的开销,主要是内存的开销

一、相关实际问题 内核是如何管理内存的如何查看内核使用的内存信息服务器上一条ESTABLISH状态的空连接需要消耗多少内存机器上出现了3万多个TIME_WAIT&#xff0c;内存开销会不会很大 二、Linux内核如何管理内存 内核针对自己的应用场景&#xff0c;使用了一种叫做SLAB/SLU…

第三十四篇:URL和URI的区别,HTTP系列一

前面我们讲到通过TCP协议通信双方建立可靠连接&#xff0c;那么此时双方进行通信&#xff0c;需要用人能理解的形式进行信息组织&#xff0c;也就是为各种特定需求服务&#xff0c;满足日常生活中的各种场景。 比如&#xff1a;网页浏览、电子邮件、远程登录、文件传输、网络管…

4499元起!苹果发布新款Mac mini:升级M4/M4 Pro 仅手掌大小

10月30日消息&#xff0c;今晚不仅是小米发布了重磅旗舰&#xff0c;苹果也带来了重磅升级后的新款Mac mini。 目前已经上架官网&#xff0c;采用全新外观设计&#xff0c;仅仅只有手掌大小&#xff0c;可以直接托在手心&#xff0c;不过厚度相对增加了一些&#xff0c;具体尺寸…

Golang | Leetcode Golang题解之第522题最长特殊序列II

题目&#xff1a; 题解&#xff1a; func isSubseq(s, t string) bool {ptS : 0for ptT : range t {if s[ptS] t[ptT] {if ptS; ptS len(s) {return true}}}return false }func findLUSlength(strs []string) int {ans : -1 next:for i, s : range strs {for j, t : range s…

b站小土堆PyTorch视频学习笔记(CIFAR10数据集分类实例)

1、准备数据集并查看数据集长度 train_data torchvision.datasets.CIFAR10(root"./data", trainTrue, transformtorchvision.transforms.ToTensor(), downloadTrue) test_data torchvision.datasets.CIFAR10(root"./data", trainFalse, transformtorch…

ESP8266 连接 MQTT 服务器EMQX 连接MQTTX

目录 1.先用有一台自己的云服务器 2. 使用FinalShell连接阿里云云服务器ECS 3.安装宝塔 4.在云服务器打开8888端口 5.使用外网面板地址打开宝塔面板 6.安装Docker 7.下载emqx 8.打开emqxWeb 界面 9.下载MQTTX 10.EMQX加一个客户端 11.开始通信 12.加入单片机ESP8266 …

开源代码管理平台Gitlab如何本地化部署并实现公网环境远程访问私有仓库

文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 前言 本文主要介绍如何在Linux CentOS8 中搭建GitLab私有仓库并且结合内网穿透工具实现在公网…

【1个月速成Java】基于Android平台开发个人记账app学习日记——第4天,注册登录功能设计

24.11.03 1.修改项目目录 从今天开始将正式进行功能的设计&#xff0c;首先需要对原来的项目结构进行修改&#xff0c;主要是添加新的文件夹用于存放新的文件。下面进行展示和讲解&#xff1a; 我用红圈圈出了新添加的文件夹&#xff0c;介绍下它们都是干啥的&#xff1a; da…