Java CAS底层原理
Java CAS底层原理
Java CAS底层原理,这一篇就够了!!!
CAS全称(Conmpare And Swap)比较并交换,是一种用于在多线程环境下实现同步功能的机制。CAS 操作包含三个操作数 – 内存地址、预期值和新值。CAS 的实现逻辑是将内存地址的数值与预期数值想比较,若相等,则将内存位置处的值替换为新值。若不相等,则不做任何操作。
JAVA中CAS是通过自旋操作完成赋值,若值不相等再更新预期值、重新计算新值,接着进行CAS操作,直到成功为止。底层是JVM调用操作系统原语指令unsafe
,并由CPU完成原子操作,你要知道并发/多线程环境下如果CPU没有原子操作我们是无法完成。
- JAVA1.5开始引入了CAS,主要代码都放在JUC的atomic包下,如下图:
- JUC包下源码如下:
- 每一个操作都是调用
unsafe
方法实现结果。这是java自旋完成CAS源码:
CAS优点
- 没有引用锁的概念,并发量不高情况下提高效率
- 减少线程上下文切换
CAS缺点
- cpu开销大,在高并发下,许多线程,更新一变量,多次更新不成功,循环反复,给cpu带来大量压力。
- 只是一个变量的原子性操作,不能保证代码块的原子性。
- ABA问题
ABA问题
CAS带来最大问题就是ABA问题。有A、B两个线程,A线程运行10s,B线程运行2s,两个线程同一时间开始运行都修改同一变量m,假设m初始值为5,B线程修改m值5改为10,再修改m值10改为5。此时A线程修改m值5改为6,修改成功,满足CAS操作原理,而A线程认为m一直都是5,它并不知道m的值已经被修改过。
解决该问题通过添加版本号来解决,每次修改都带着本次修改的版本号,发现版本不是当前版本此修改失败,否则修改成功。如果自旋同理重新获得版本号计算旧值、新值等。
public class ABA {//ABA问题产生与解决static AtomicReference<Integer> atomicReference = new AtomicReference<>(100);static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100, 1);public static void main(String[] args) {//==========ABA问题的产生==========System.out.println("==========ABA问题的产生==========");new Thread(() -> {atomicReference.compareAndSet(100, 101);atomicReference.compareAndSet(101, 100);}, "t1").start();new Thread(() -> {//保证t1线程完成try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(atomicReference.compareAndSet(100, 2019) + "\t" + atomicReference.get());}, "t2").start();//暂停一会try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}//==========ABA问题的解决==========System.out.println("==========ABA问题的解决==========");new Thread(() -> {int stamp = atomicStampedReference.getStamp();System.out.println(Thread.currentThread().getName() + "\t第一次版本号:" + stamp);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}atomicStampedReference.compareAndSet(100, 101, stamp, stamp + 1);System.out.println(Thread.currentThread().getName() + "\t第二次版本号:" + atomicStampedReference.getStamp());atomicStampedReference.compareAndSet(101, 100, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1);System.out.println(Thread.currentThread().getName() + "\t第三次版本号:" + atomicStampedReference.getStamp());}, "t3").start();new Thread(() -> {int stamp = atomicStampedReference.getStamp();System.out.println(Thread.currentThread().getName() + "\t第一次版本号:" + stamp);try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}boolean result = atomicStampedReference.compareAndSet(100, 101, stamp, stamp + 1);System.out.println(Thread.currentThread().getName() + "\t修改成功否" + result + "\t当前最前版本号:" + atomicStampedReference.getStamp());System.out.println(Thread.currentThread().getName() + "\t当前实际值:" + atomicStampedReference.getReference());}, "t4").start();}
}
- 运行结果:
Java CAS底层原理相关推荐
- java底层原理书籍_不愧是阿里p8大佬!终于把Java 虚拟机底层原理讲清楚了,请签收...
概述 JVM 的内存模型和 JVM 的垃圾回收机制一直是 Java 业内从业者绕不开的话题(实际调优.面试)JVM是java中很重要的一块知识,也是面试常问的问题之一,直至今天,仍然还有许多面试者在被 ...
- 10分钟看懂, Java NIO 底层原理
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 写在前面 ...
- 面试突然问Java多线程底层原理,我哭了!
兄弟们,不要踩坑啊,我原本打算在金九银十之前换份工作,结果出去第一面就被干懵了! 面试官上来就问我了解不了解多线程,我感觉我还可以,我就和他说:必须的! 不过,他直接问了多线程的底层原理,这我都是一知 ...
- Java NIO 底层原理详解
写在前面 很多的小伙伴,被java IO 模型,搞得有点儿晕,一会儿是4种模型,一会儿又变成了5种模型. 很多的小伙伴,也被nio这个名词搞晕了,一会儿java 的nio 不叫 非阻塞io,一会儿ja ...
- 10分钟看懂 Java NIO 底层原理
写在前面 很多的小伙伴,被java IO 模型,搞得有点儿晕,一会儿是4种模型,一会儿又变成了5种模型. 很多的小伙伴,也被nio这个名词搞晕了,一会儿java 的nio 不叫 非阻塞io,一会儿ja ...
- Java集合底层原理理解
Java集合 List,Set,Map三者区别 List 顺序的好帮手:存储一组不唯一的有序的对象 Set 注重独一无二的性质:不允许重复的集合 Map 用key来搜索:使用键值对存储.两个key可以 ...
- java i 底层原理,《Java基础知识》Java Hash底层原理
前言 了解到JDK8对HashMap进行了优化,就一起了解一下JDK8的HashMap. 原理 1. 哈希表的原理 首先需要一张Hash表,Java通过数据实现:默认长度位16,并且. 第一步插入张三 ...
- Java Stream 底层原理
Stream API 你可能没意识到Java对函数式编程的重视程度,看看Java 8加入函数式编程扩充多少功能就清楚了.Java 8之所以费这么大功夫引入函数式编程,原因有二: 代码简洁函数式编程写出 ...
- Java反射底层原理以及应用
写在前面: Java反射, 这个东西百度就会出来相关概念: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动 ...
最新文章
- 中删除某几列_算法--apriori 实战 (某零售企业的商品关联分析)
- Java基础与实践题库_Java程序设计基础与实践(题库版)
- swagger Illegal DefaultValue null for parameter type integer
- 这70个Java必背英语单词不会,就别说你是Java程序员!
- PhoneGap 安装体验
- 微信小程序隐藏标题栏navigationBar的方法
- 图像聚类与检索的简单实现(一)
- Classes in JScript – Part III 类的继承与封装
- 上海博彦科技 千万别来_这个年产值2870亿元的科技园区,将率多家企业亮相本届服贸会...
- python3 打印_Python 3 进阶 —— print 打印和输出
- 反射封装工具类-----零SQL插入
- ElasticSearch D3
- 加密软件漏洞评测系统_苹果向用户推送macOS Big Sur 11.0.1正式版系统_华强北软件网_软件行情_软件新闻_软件评测_手机应用文章...
- java jwks_OIDC中JWK,JWKS的介绍与使用
- JavaScript初阶(十)---------- 数组
- STM32寄存器操作端口模式SDA_OUT()/SDA_IN()
- JavaScript函数重载(js函数重载)
- 第十三次博文:教你从立创EDA库导入AD库,保姆级别!
- Office2010安装需要MSXML版本6.10.1129.0的方法
- Power Query For Excel数据处理利器