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

[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.mrgr.cn/news/61756.html

相关文章:

  • 数据结构
  • 《自动驾驶技术的深度思考:安全与伦理的挑战》
  • ChangeCLIP环境配置
  • 制氮机分子筛的材质选择
  • php伪协议和move_uploaded_file、rename、copy等文件操作
  • Vue笔记-element ui中关于table的前端分页
  • 计算机组成原理之高级语言程序与机器级代码之间的对应、高级语言和机器级代码的具体示例
  • 优化云成本,打造卓越体验,他们有话说
  • 微信小程序 - 获取汉字拼音首字母(汉字英文首字母)根据汉字查拼音,实现汉字拼音首字母获取,在小程序上实现汉字的拼音提取首字母!
  • [专有网络VPC]管理VPC配额
  • 智慧园区 | 数智引领,让智慧触手可及
  • String的长度有限,而我对你的思念却无限延伸
  • IDEA 打包首个java项目为jar包
  • 开箱即用!智能文档处理“百宝箱”
  • Faces in Things数据集: 由麻省理工学院、微软等联合发布,探索人类视觉错觉的新里程碑
  • Ollama运行本地LLM大模型简单教程:大显存很重要
  • 【Golang】Golang的数组和slice切片的区别
  • 数据集(Dataset)是指为特定目的而收集、整理、存储的数据集合
  • 雷池社区版配置同步试用
  • 最长公共子串问题
  • 【Linux系统编程】第三十九弹---探索信号处理的奥秘:阻塞信号与sigset_t的深入剖析及实战
  • BUUCTF靶场Misc练习
  • yarn 下载安装、下载依赖、通过 vscode 运行服务(Windows11)
  • 企业如何提高外呼电话接通率?申请来电名片需要什么材料?
  • 数据驱动的智能化投资:民锋金融科技创新的策略分析
  • Linux权限管理中的文件权限与目录权限