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

CAS很好理解

CAS的实现

compareAndSwap()通过三个参数 V,E,N 实现,V是要更新的变量,E是预期值,N是新值。当V的值等于E值时,将V的值设为N,否则说明存在已经被其他线程更新。

compareAndSwap()是native方法,底层实现中,在多核CPU环境下,会增加一个Lock指令对缓存或总线加锁,从而保证比较并替换这两个指令的原子性。这里注意变量要加volatile。

ABA问题

  1. 线程 T1 读取到某个变量 A 的值。
  2. 在 T1 进行下一步操作之前,线程 T2 将该变量的值从 A 改为 B,然后又改回 A。
  3. 线程 T1 此时仍然认为变量的值没有被其他线程修改过(因为它看到的值仍然是 A),于是继续执行。

如何解决ABA问题?

增加版本号

使用一个附加的版本号,每次更新变量时同时更新版本号。通过比较版本号而非单纯比较值来判断变量是否被修改。

使用更高层次的锁

使用ReentrantLock或者synchronized更高级别的锁代替CAS。

使用AtomicStampedReference替代

AtomicStampedReference 是 Java 并发包(java.util.concurrent.atomic 包)中的一个类,用于解决 ABA 问题。它通过引入一个额外的整数 "戳" (stamp)来跟踪引用的版本,每次更新引用时同时更新戳,从而避免仅通过引用判断是否发生变化所导致的 ABA 问题。

public static void main(String[] args) {String initialRef = "initial value";int initialStamp = 0;AtomicStampedReference<String> atomicStampedRef = new AtomicStampedReference<>(initialRef, initialStamp);// 获取当前引用值和戳int[] stampHolder = new int[1];String currentRef = atomicStampedRef.get(stampHolder);int currentStamp = stampHolder[0];System.out.println("Initial: Reference = " + currentRef + ", Stamp = " + currentStamp);// 模拟 ABA 问题atomicStampedRef.compareAndSet(currentRef, "new value", currentStamp, currentStamp + 1);atomicStampedRef.compareAndSet("new value", initialRef, currentStamp + 1, currentStamp + 2);// 尝试使用旧的引用和戳更新boolean isUpdated = atomicStampedRef.compareAndSet(currentRef, "another new value", currentStamp, currentStamp + 1);System.out.println("Update succeeded: " + isUpdated); // Output will be falseSystem.out.println("After update: Reference = " + atomicStampedRef.getReference() + ", Stamp = " + atomicStampedRef.getStamp());// 再次获取当前引用值和戳currentRef = atomicStampedRef.get(stampHolder);currentStamp = stampHolder[0];System.out.println("Final: Reference = " + currentRef + ", Stamp = " + currentStamp);
}
http://www.xdnf.cn/news/125641.html

相关文章:

  • WebAssembly:开启高性能Web应用新时代
  • 技术视界 | 数据的金字塔:从仿真到现实,机器人学习的破局之道
  • 使用QML Tumbler 实现时间日期选择器
  • Kubernetes 常用运维命令整理
  • TypeScript 开发实战:如何安全替换字符串中的关键字
  • C#源码分析 --- Random
  • CentOS 7 磁盘阵列搭建与管理全攻略
  • 2. Linux开发工具
  • 系统架构师/软件设计师--选择题概念题口诀与公式计算
  • 如何在windows10上英伟达gtx1060上部署通义千问-7B-Chat
  • 安恒web安全春招实战
  • AI生成内容版权管理:数字时代企业的风险防控与价值保障
  • SEO的关键词研究与优化 第一章
  • 门对讲机市场报告:预计2031年全球销售额将达到36.29亿美元
  • ArkUI常用的组件
  • 【Spec2MP:项目管理之项目风险管理】
  • 银河麒麟系统离线安装nodejs
  • Sharding-JDBC 系列专题 - 第八篇:数据治理与高级功能
  • 大屏资源汇总
  • AI在论文评审中的应用与工具推荐
  • python版本得数独游戏
  • Nest集成健康检查
  • Redis中的hash数据结构设置过期时间的坑!!!
  • 纯真社区IP库离线版发布更新
  • 2025年3月电子学会青少年机器人技术(五级)等级考试试卷-理论综合
  • LeetCode算法题(Go语言实现)_59
  • Java函数式编程深度解析:从Lambda到流式操作
  • Allegro23.1新功能之铜皮替换成Via功能操作指导
  • PowerBI-使用参数动态修改数据源路径
  • 注意力机制:Transformer如何用“数学凝视“统治AI?