CAS 一些隐藏的知识,您了解吗
目录
ConcurrentHashMap 一定是线程安全的吗
CAS 机制的注意事项
使用java 并行流 ,您要留意了
ConcurrentHashMap 在JDK1.8中ConcurrentHashMap 内部使用的是数组加链表加红黑树的结构,通过CAS+volatile或synchronized的方式来保证线程安全的,这些原理已毋庸置疑,一言不合上代码.
1. 模拟2个线程累计,通过ConcurrentHashMap 储存累计的结果。
/*** @description: ConcurrentHashMap 真的安全吗* @author: ppx* @date: 2023/8/17 14:11* @version: 1.0*/
public class TestMap {private static ConcurrentHashMap<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();private static String key = "hello";/*** @description: 测试2个线程 执行计算* @param:* @return: void* @author: ppx* @date: 2023/8/17 16:43*/private static void testRun() {ExecutorService executor = new ThreadPoolExecutor(2, 5,2L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());for (int i = 0; i < 2; i++) {executor.submit(() -> {for (int j = 0; j < 5; j++) {// 第一步读取int value = concurrentHashMap.getOrDefault(key, 0);// 第二步+1value++;// 第三补+ 回写mapconcurrentHashMap.put(key, value);}});}executor.shutdown();// 直到线程执行完成while(!executor.isTerminated()){}System.out.println("执行结果:" + concurrentHashMap.get(key));}public static void main(String[] args) {testRun();}
}
2.出乎意料执行多次输出不同的结果:



3. 分析原理:ConcurrentHashMap 本身是线程安全的,但for 里面的获map取值、加加操作及回写map 这三步是非原子性。要保证操作的安全性,这三步实现原子性即可。

优化后代码:
private static void testRun() {ExecutorService executor = new ThreadPoolExecutor(2, 5,2L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());for (int i = 0; i < 2; i++) {executor.submit(() -> {for (int j = 0; j < 5; j++) {synchronized (TestMap.class) {int value = concurrentHashMap.getOrDefault(key, 0);value ++;concurrentHashMap.put(key, value);}}});}executor.shutdown();while (!executor.isTerminated()) {}System.out.println("执行结果:" + concurrentHashMap.get(key));}
CAS 机制的注意事项
某线程把数据A更新了B,随后又从B更新成A,恰好此时另一线程读取该数据,发现数据的值还是A没有变化,误认为还是原来的A,但此时A的一些属性或状态已经发生过变化。
CAS操作中将判断“V的值是否仍然为A?”,如果是的话将执行更新操作,在某些CAS操作中,如果V的值首先由A变为B,再由B变为A,那么CAS仍然将会操作成功。
ABA问题:
线程A 的操作,cas中的值由1变成99,再由99变成1,此次线程B 发现AtomicInteger 的值还是1,于是更新到50,产生ABA的问题。
private static AtomicInteger atomicInteger = new AtomicInteger(1);public static void main(String[] args) {Thread threadA = new Thread(() -> {atomicInteger.compareAndSet(1, 99);atomicInteger.compareAndSet(99, 1);System.out.println("线程A进行CAS后的值:"+atomicInteger.get());try {Thread.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}}, "线程A");Thread threadB = new Thread(() -> {try{atomicInteger.compareAndSet(1, 50);System.out.println("线程B进行CAS后的值:"+atomicInteger.get());}catch (Exception e) {e.printStackTrace();}}, "线程B");threadA.start();try {threadA.join();} catch (InterruptedException e) {e.printStackTrace();}threadB.start();}
基于AtomicStampedReference类实现
AtomicStampedReference内部增加了版本号的概念,只有期待的值与版本号分别匹配后,才满足条件,更新最新的值。
案例:
线程 A 进行CAS 操作更新时,发布版本已发生变动,CAS更新 失败。线程B 进行CAS 操作更新时,匹配对应的版本,期待值,更新成功。
public static void main(String[] args) {new Thread(() -> {// 让线程B 获取最新版本号,成功 执行更新try {Thread.sleep(11);} catch (InterruptedException e) {e.printStackTrace();}int stamp = atomicStampedReference.getStamp();System.out.println(Thread.currentThread().getName() + ", 当前版本号为:" + stamp);boolean firstCasFlag = atomicStampedReference.compareAndSet(100, 99, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1);System.out.println("当前版本号:"+atomicStampedReference.getStamp()+", 线程A进行CAS后的值:" + atomicInteger.get() + ",第1次操作是否修改成功: " + firstCasFlag);}, "线程A").start();new Thread(() -> {try {int stamp = atomicStampedReference.getStamp();System.out.println(Thread.currentThread().getName() + ", 版本号为:" + atomicStampedReference.getStamp());boolean flag = atomicStampedReference.compareAndSet(100, 888, stamp, atomicStampedReference.getStamp() + 1);System.out.println("线程B进行CAS后的值:" + atomicStampedReference.getReference() + ", 此次操作是否修改成功: " + flag);} catch (Exception e) {e.printStackTrace();}}, "线程B").start();}
执行结果:
线程B, 版本号为:1
线程B进行CAS后的值:888, 此次操作是否修改成功: true
线程A, 当前版本号为:2
当前版本号:2, 线程A进行CAS后的值:1,第1次操作是否修改成功: false
相关文章:
CAS 一些隐藏的知识,您了解吗
目录 ConcurrentHashMap 一定是线程安全的吗 CAS 机制的注意事项 使用java 并行流 ,您要留意了 ConcurrentHashMap 在JDK1.8中ConcurrentHashMap 内部使用的是数组加链表加红黑树的结构,通过CASvolatile或synchronized的方式来保证线程安全的,这些原理…...
ChatGPT逐句逐句地解释代码并分析复杂度的提示词prompt
前提安装chrome 插件 AI Prompt Genius, 请参考 3 个 ChatGPT 插件您需要立即下载 你是首席软件工程师。请解释这段代码:{{code}} 添加注释并重写代码,用注释解释每一行代码的作用。最后分析复杂度。快捷键 / 选择 Explain Code 输入代码提…...
【Lua语法】算术、条件、逻辑、位、三目运算符
1.算术运算符 加减乘除取余: - * / % Lua中独有的:幂运算 ^ 注意: 1.Lua中没有自增自减(、–),也没有复合运算符(、-) 2.Lua中字符串可以进行算术运算符操作,会自动转成number 如:“10.3” 1 结果为11.3…...
Cygwin 配置C/C++编译环境以及如何编译项目
文章目录 一、安装C、C编译环境需要的包1. 选择gcc-core、gcc-g2. 选择gdb3. 选择mingw64下的gcc-core、gcc-g4. 选择make5. 选择cmake6. 确认更改7. 查看包安装状态 二、C、C 项目编译示例step1:解压缩sed-4.9.tar.gzstep2:执行./configure生成Makefile…...
回归预测 | MATLAB实现FA-BP萤火虫算法优化BP神经网络多输入单输出回归预测(多指标,多图)
回归预测 | MATLAB实现FA-BP萤火虫算法优化BP神经网络多输入单输出回归预测(多指标,多图) 目录 回归预测 | MATLAB实现FA-BP萤火虫算法优化BP神经网络多输入单输出回归预测(多指标,多图)效果一览基本介绍程…...
【100天精通python】Day39:GUI界面编程_PyQt 从入门到实战(下)_图形绘制和动画效果,数据可视化,刷新交互
目录 专栏导读 6 图形绘制与动画效果 6.1 绘制基本图形、文本和图片 6.2 实现动画效果和过渡效果 7 数据可视化 7.1 使用 Matplotlib绘制图表 7.2 使用PyQtGraph绘制图表 7.3 数据的实时刷新和交互操作 7.3.1 数据的实时刷新 7.3.2 交互操作 7.4 自定义数据可视化…...
Java课题笔记~ Ajax
1.1 概述 AJAX (Asynchronous JavaScript And XML):异步的 JavaScript 和 XML。 我们先来说概念中的 JavaScript 和 XML,JavaScript 表明该技术和前端相关;XML 是指以此进行数据交换。 1.1.1 作用 AJAX 作用有以下两方面: 与服…...
调整mysql 最大传输数据 max_allowed_packet=500M
查看 -- show VARIABLES like %max_allowed_packet%; -- set global max_allowed_packet 1024*1024*64;-- show variables like %timeout%; -- show global status like com_kill; show global variables like max_allowed_packet; -- set global max_allowed_packet1024*102…...
【工具】 删除Chrome安装的“创建快捷方式”
创建Chrome的快捷方式,可以放在桌面,想用时双击就可以打开网页,比书签(brookmark)结构化管理更方便。 但是,安装一时爽,卸载有问题。 如果用 windows 控制面板\所有控制面板项\程序和功能 卸载…...
windows上的docker自动化部署到服务器脚本
1、mvn install后,双击这个bat,实现docker build后上传到124服务器,并且重启124服务器 **echo offsetlocal:: 定义镜像名称和版本变量 set IMAGE_NAMEweb set IMAGE_VERSION1.3.1:: 清理本地文件 echo Cleaning up... del service-%IMAGE_N…...
VoxWeekly|The Sandbox 生态周报|20230814
欢迎来到由 The Sandbox 发布的《VoxWeekly》。我们会在每周发布,对上一周 The Sandbox 生态系统所发生的事情进行总结。 如果你喜欢我们内容,欢迎与朋友和家人分享。请订阅我们的 Medium 、关注我们的 Twitter,并加入 Discord 社区…...
Aurora 8B/10B
目录 1. Overview2. Feature List2. Block Diagram3. Ports Description3.1. User InterfaceFraming InterfaceStreaming InterfaceUser Flow Control(UFC)Native Flow Control(NFC) 3.2. Status and Control Ports3.3. Transceiv…...
如何关闭“若要接收后续google chrome更新,您需使用windows10或更高版本”
Windows Registry Editor Version 5.00[HKEY_CURRENT_USER\Software\Policies\Google\Chrome] "SuppressUnsupportedOSWarning"dword:00000001 如何关闭“若要接收后续 google chrome 更新,您需使用 windows 10 或更高版本” - 知乎...
python中使用xml快速创建Caption和URL书签管理器应用程序
导语: 本文介绍如何使用wxPython库创建一个Caption和URL管理器应用程序。该应用程序具有图形用户界面,允许用户输入Caption和URL,并将其保存到XML文件中。此外,还提供了浏览文件夹并选择HTML文件的功能,并可以运行另一…...
分类预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机多输入分类预测
分类预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机多输入分类预测 目录 分类预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机多输入分类预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.分类预测 | MATLAB实现DBN-SVM深度置信网络结合支持向量机多输入分…...
Vue中使用v-bind:class动态绑定多个类名
Vue.js是一个流行的前端框架,它可以帮助开发者构建动态交互的UI界面。在Vue.js开发中,经常需要动态绑定HTML元素的class(类名)属性,以改变元素的外观和行为。本文将介绍采用v-bind:class指令在Vue中如何动态绑定多个类…...
深入了解Maven(一)
目录 一.Maven介绍与功能 二.依赖管理 1.依赖的配置 2.依赖的传递性 3.排除依赖 4.依赖的作用范围 5.依赖的生命周期 一.Maven介绍与功能 maven是一个项目管理和构建工具,是基于对象模型POM实现。 Maven的作用: 便捷的依赖管理:使用…...
PostgreSQL中的密码验证方法
假设您想在客户端/服务器协议中实现密码身份验证方法。 您将如何做到这一点以及可能出现的问题是什么? 以下是 PostgreSQL 中如何完成此操作的故事。 password 一开始,PostgreSQL 只有 pg_hba.conf 中现在称为“password”的方法。 这是你能想象到的最…...
【微信小程序】小程序之间的跳转方式总结
想要从该小程序跳转到其他小程序怎么做? 方式 小程序之间的跳转方法有: wx.navigateTo:保留当前页面,跳转到应用内的某个页面,然后从该页面返回上一页的时候使用wx.navigateBack返回。wx.switchTab:跳转…...
基于Mysqlrouter+MHA+keepalived实现高可用半同步 MySQL Cluster项目
目录 项目名称: 基于Mysqlrouter MHA keepalived实现半同步主从复制MySQL Cluster MySQL Cluster: 项目架构图: 项目环境: 项目环境安装包: 项目描述: 项目IP地址规划: 项目步骤: 一…...
像素幻梦·创意工坊应用场景:独立音乐人专辑封面像素艺术生成流程
像素幻梦创意工坊应用场景:独立音乐人专辑封面像素艺术生成流程 1. 引言:像素艺术在音乐视觉中的价值 在数字音乐时代,专辑封面依然是艺术家表达音乐理念的重要载体。对于独立音乐人而言,独特的视觉风格往往能成为作品的标志性符…...
万物识别镜像高级功能探索:除了基础识别,还能做什么?
万物识别镜像高级功能探索:除了基础识别,还能做什么? 1. 万物识别镜像的隐藏潜力 大多数人使用万物识别镜像时,只停留在基础识别功能上——上传图片,获取识别结果。但这款基于cv_resnest101_general_recognition算法…...
格式化字符串漏洞利用的5种常见手法:以CTFshow题目为例
格式化字符串漏洞实战:5种高级利用手法与CTFshow案例分析 格式化字符串漏洞(Format String Vulnerability)是二进制安全领域中最经典也最危险的漏洞类型之一。这种漏洞源于程序员错误地将用户输入直接作为格式化字符串参数传递给printf、spri…...
AI辅助开发:让快马AI智能生成自适应Win10镜像下载管理工具
AI辅助开发:让快马AI智能生成自适应Win10镜像下载管理工具 最近在折腾一个Windows系统镜像下载管理工具,发现传统下载方式存在不少痛点:下载源选择困难、网络波动导致中断、版本特性不透明。正好接触到InsCode(快马)平台的AI辅助开发功能&am…...
Asian Beauty Z-Image Turbo基础教程:如何修改默认提示词实现‘旗袍少女’‘水墨仕女’风格
Asian Beauty Z-Image Turbo基础教程:如何修改默认提示词实现‘旗袍少女’‘水墨仕女’风格 想用AI画出充满东方韵味的“旗袍少女”或“水墨仕女”,但试了很多模型,出来的效果总是不对味?要么人物五官太西化,要么画面…...
从特效 SDK 到 AI 动效平台:Neon Vibe Motion 的技术演进之路
多媒体中台在 B 站主要负责剪辑、拍摄、直播等业务场景的动效渲染,开发维护的 SDK 在后文统一称为特效 SDK。 传统的视频特效生产一般分三条链路: 三条链路存在一个困境:效果丰富度、实时可交互、生产效率,三者不可兼得。 那么能…...
解码汽车ECU的“健康档案”:剖析吉利Basetech五大运行周期计数器(OCC)的协同诊断逻辑
1. 汽车ECU的“健康档案”是什么? 当你去医院体检时,医生会查看你的病历记录、化验报告和近期症状,综合判断你的健康状况。汽车ECU(电子控制单元)也有类似的"健康档案",它就是吉利Basetech技术中…...
有线/无线(空口)抓包过程及其分析
一、如何判断该抓有线包,还是无线包层级问题类型抓包位置L1/L2(无线)连不上、掉线、弱信号无线抓包L2(有线)VLAN错误有线抓包L3(IP)DHCP失败有线抓包L4(传输)丢包、重传有…...
STM32duino多传感器库:X-NUCLEO-IKS01A2驱动详解
1. 项目概述STM32duino X-NUCLEO-IKS01A2 是一个面向 Arduino 兼容生态(特别是基于 STM32 的开发板,如 NUCLEO-F401RE、NUCLEO-F411RE、NUCLEO-L476RG 等)的硬件抽象库,专为驱动 STMicroelectronics 官方推出的 X-NUCLEO-IKS01A2 …...
终极指南:如何彻底解决Colab运行text-generation-webui的Matplotlib后端错误
终极指南:如何彻底解决Colab运行text-generation-webui的Matplotlib后端错误 【免费下载链接】text-generation-webui The original local LLM interface. Text, vision, tool-calling, training, and more. 100% offline. 项目地址: https://gitcode.com/GitHub_…...
