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底层原理相关推荐

  1. java底层原理书籍_不愧是阿里p8大佬!终于把Java 虚拟机底层原理讲清楚了,请签收...

    概述 JVM 的内存模型和 JVM 的垃圾回收机制一直是 Java 业内从业者绕不开的话题(实际调优.面试)JVM是java中很重要的一块知识,也是面试常问的问题之一,直至今天,仍然还有许多面试者在被 ...

  2. 10分钟看懂, Java NIO 底层原理

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 写在前面 ...

  3. 面试突然问Java多线程底层原理,我哭了!

    兄弟们,不要踩坑啊,我原本打算在金九银十之前换份工作,结果出去第一面就被干懵了! 面试官上来就问我了解不了解多线程,我感觉我还可以,我就和他说:必须的! 不过,他直接问了多线程的底层原理,这我都是一知 ...

  4. Java NIO 底层原理详解

    写在前面 很多的小伙伴,被java IO 模型,搞得有点儿晕,一会儿是4种模型,一会儿又变成了5种模型. 很多的小伙伴,也被nio这个名词搞晕了,一会儿java 的nio 不叫 非阻塞io,一会儿ja ...

  5. 10分钟看懂 Java NIO 底层原理

    写在前面 很多的小伙伴,被java IO 模型,搞得有点儿晕,一会儿是4种模型,一会儿又变成了5种模型. 很多的小伙伴,也被nio这个名词搞晕了,一会儿java 的nio 不叫 非阻塞io,一会儿ja ...

  6. Java集合底层原理理解

    Java集合 List,Set,Map三者区别 List 顺序的好帮手:存储一组不唯一的有序的对象 Set 注重独一无二的性质:不允许重复的集合 Map 用key来搜索:使用键值对存储.两个key可以 ...

  7. java i 底层原理,《Java基础知识》Java Hash底层原理

    前言 了解到JDK8对HashMap进行了优化,就一起了解一下JDK8的HashMap. 原理 1. 哈希表的原理 首先需要一张Hash表,Java通过数据实现:默认长度位16,并且. 第一步插入张三 ...

  8. Java Stream 底层原理

    Stream API 你可能没意识到Java对函数式编程的重视程度,看看Java 8加入函数式编程扩充多少功能就清楚了.Java 8之所以费这么大功夫引入函数式编程,原因有二: 代码简洁函数式编程写出 ...

  9. Java反射底层原理以及应用

    写在前面: Java反射, 这个东西百度就会出来相关概念: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动 ...

最新文章

  1. 中删除某几列_算法--apriori 实战 (某零售企业的商品关联分析)
  2. Java基础与实践题库_Java程序设计基础与实践(题库版)
  3. swagger Illegal DefaultValue null for parameter type integer
  4. 这70个Java必背英语单词不会,就别说你是Java程序员!
  5. PhoneGap 安装体验
  6. 微信小程序隐藏标题栏navigationBar的方法
  7. 图像聚类与检索的简单实现(一)
  8. Classes in JScript – Part III 类的继承与封装
  9. 上海博彦科技 千万别来_这个年产值2870亿元的科技园区,将率多家企业亮相本届服贸会...
  10. python3 打印_Python 3 进阶 —— print 打印和输出
  11. 反射封装工具类-----零SQL插入
  12. ElasticSearch D3
  13. 加密软件漏洞评测系统_苹果向用户推送macOS Big Sur 11.0.1正式版系统_华强北软件网_软件行情_软件新闻_软件评测_手机应用文章...
  14. java jwks_OIDC中JWK,JWKS的介绍与使用
  15. JavaScript初阶(十)---------- 数组
  16. STM32寄存器操作端口模式SDA_OUT()/SDA_IN()
  17. JavaScript函数重载(js函数重载)
  18. 第十三次博文:教你从立创EDA库导入AD库,保姆级别!
  19. Office2010安装需要MSXML版本6.10.1129.0的方法
  20. Power Query For Excel数据处理利器

热门文章

  1. ArcGIS导入Excel经纬度坐标数据及解决显示出错
  2. Linux kworker 占用CPU过高
  3. python的matplotlib.pyplot绘制甘特图
  4. Angular5 Component通信
  5. 二、Git安装与配置
  6. 18个数围成一圈,求相邻三数之和最大数(C)
  7. 运放电路:运算放大器的同相放大和反相放大
  8. 中秋送礼蓝牙耳机有哪些?高质量蓝牙耳机推荐
  9. 【ZYNQ Ultrascale+ MPSOC FPGA教程】第十六章 7寸液晶屏显示实验
  10. UE4使用GameInstance设置全局变量(不同关卡、类之间数据传递)