一、CAS 是什么?

CAS(Compare And Swap),比较并交换,它是一条CPU并发原语。它的功能是判断内存某个位置的值是否为预期值,如果是则更新为新的值,这个过程是原子的。1 public class CASDemo {

2 public static void main(String[] args) {

3 AtomicInteger atomicInteger = new AtomicInteger(5);

4

5 System.out.print(atomicInteger.compareAndSet(5, 2019));

6 System.out.println(" the value are " + atomicInteger.get());

7

8 System.out.print(atomicInteger.compareAndSet(5, 1024));

9 System.out.println(" the value are " + atomicInteger.get());

10 }

11 }

CAS 并发原语体现在 Java 语言中就是 sun.misc.Unsafe 类中的各个方法。调用 Unsafe 类中的 CAS 方法,JVM 会帮我们实现 CAS 汇编指令。这是一种完全依赖于硬件的功能,通过它实现了原子操作,再次强调,由于CAS 是一种系统原语,原语属于操作系统用语范畴,是由若干条指令组成,用于完成某个功能的一个过程,并且原语的执行必须是连续的,在执行过程中不允许中断,也就是说 CAS 是一条原子指令,不会造成所谓的数据不一致的问题。

二、Unsafe 类

以 AtomicInteger 原子类为例:1 public class AtomicInteger extends Number implements java.io.Serializable {

2 private static final long serialVersionUID = 6214790243416807050L;

3

4 // setup to use Unsafe.compareAndSwapInt for updates

5 private static final Unsafe unsafe = Unsafe.getUnsafe();

6 private static final long valueOffset;

7

8 static {

9 try {

10 valueOffset = unsafe.objectFieldOffset

11 (AtomicInteger.class.getDeclaredField("value"));

12 } catch (Exception ex) { throw new Error(ex); }

13 }

14

15 private volatile int value;

16

17 // ...

18 }

2.1 参数解析UnSafe是CAS的核心类。由于Java 方法无法直接访问底层,需要通过本地(native)方法来访问,UnSafe相当于一个后门,基于该类可以直接操作特定内存的数据。Unsafe 类在于 sun.misc 包中,其内部方法操作可以像 C 的指针一样直接操作内存,因为 Java 中 CAS 操作的执行依赖于 Unsafe 类的方法。

注意:Unsafe 类中所有的方法都是 native 修饰的,也就是说 Unsafe 类中的方法都是直接调用操作底层资源执行相应任务。

变量 valueOffset,便是该变量在内存中的偏移地址,因为 Unsafe 就是根据内存偏移地址获取数据的。

变量 value 用 volatile 修饰,保证了多线程之间的可见性。

2.2 方法示例解析

以 AtomicInteger 原子类中的 getAndIncrement() 为例:1 /**

2 * AtomicInteger.java 类中的相当于自增的方法

3 */

4 public final int getAndIncrement() {

5 return unsafe.getAndAddInt(this, valueOffset, 1);

6 }

7

8 // Unsafe 类中获取指定内存区域变量的值

9 public native int getIntVolatile(Object var1, long var2);

10

11

12 /**

13 * Unsafe 类中的方法

14 * @param var1 当前 AtomicInteger 对象

15 * @param var2 变量在内存中的偏移地址

16 * @param var4 变量的增量

17 * 方法解析:

18 * 首先调用 getIntVolatile() 方法获取指定内存区域的变量的值存储到 var5 中,

19 * 要进行增值操作前,再重新从该地址获取值与 var5 比较,

20 * 如果相同,则更新 var5 的值,并返回true,取反后,退出循环,返回相加后的值;

21 * 如果不相同,返回 false,循环继续,重新取值,直到更新成功

22 */

23 public final int getAndAddInt(Object var1, long var2, int var4) {

24 int var5;

25 do {

26 var5 = this.getIntVolatile(var1, var2);

27 } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

28

29 return var5;

30 }

三、CAS 的缺点

3.1 循环时间长导致开销变大

如果 CAS 一直获取不到值,那么就会给 CPU 带来很大的开销。

3.2 只能保证一个共享变量的原子性

对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁来保证原子性。

3.3 ABA 问题

CAS算法实现一个重要前提是需要取出内存中某时刻的数据并在当下时刻比较并替换,那么在这个时间差内会导致数据的变化。

比如说一个线程 one 从内存位置 V 中取出 A,这时候另一个线程 two 也从内存中取出 A,并且线程 two 进行了一些操作将值变成了 B,然后线程 two 又将 V 位置的数据变成 A,这时候线程 one 进行CAS操作发现内存中仍然是 A,然后线程 one 操作成功。

尽管线程 one 的 CAS 操作成功,但是不代表这个过程就是没有问题的。

ABA 问题的解决可通过 java.util.concurrent.atomic.AtomicStampedReference; 带时间戳的原子引用类来解决。

标签:var5,Java,CAS,Unsafe,AtomicInteger,简述,内存,类中

来源: https://www.cnblogs.com/lveyHang/p/11883224.html

java中的case1怎么说_Java 中的 CAS 简述及原理解析相关推荐

  1. java怎么sha散列算法_Java sha1散列算法的原理解析

    Java sha1散列算法的原理解析 发布时间:2020-10-31 00:01:59 来源:亿速云 阅读:101 作者:Leah 今天就跟大家聊聊有关Java sha1散列算法的原理解析,可能很多人 ...

  2. java的对象是什么意思_Java中对象和对象引用的区别,引用、指向是什么意思

    Java的变量分为两大类:基本数据类型和引用数据类型. 其中基本类型变量有四类8种:byte short int long float double char boolean,除了8种基本数据类型变量 ...

  3. java 内存溢出和内存泄漏_JAVA中的内存溢出和内存泄漏有很大的区别

    JAVA中的内存溢出和内存泄漏分别是什么,有什么联系和区别,我谈谈自己的理解. 内存泄漏(memory leak ):申请了内存不释放,比如100m的内存,分配了10m的内存一直不回收,那么可以用的内 ...

  4. java中的方法在哪里_Java中的本机方法是什么,应在哪里使用?

    小编典典 Java中的本机方法是什么,应在哪里使用? 一旦看到一个小例子,就很清楚了: Main.java : public class Main { public native int intMet ...

  5. java中为什么要用注解_java中的注解,真的很重要,你理解了嘛?

    这篇文章开始讲解java中的注解,在平时的开发当中我相信你或多或少的接触过注解.比如你可能都见过@override,它代表的就是一个注解.但是,为了更加清晰的去介绍注解,我还是先给出一个例子,让你能够 ...

  6. java中volatile关键字的含义_java中volatile关键字的含义

    转自:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 在java线程并发处理中,有一个关键字volatile的使用目前存 ...

  7. java中map如何实现遍历_Java中如何遍历Map对象的4种方法

    在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都 ...

  8. java中容易混淆的方法_java中容易混淆的区别

    本文会随时更新一些java中容易混淆的关键字或者知识点,如有偏见之处,望留言! final和static的差别: 1,final的英语意思"最后的",在java中修饰类,方法和变量 ...

  9. java中String类是什么_Java中字符串的学习(一)String类的概述及常见方法使用

    转载请注明出处http://www.cnblogs.com/devtrees/p/4347079.html (拓展:Api:编程语言对外给我们提供的应用程序接口.) 一.概述: 我们平时上网发帖,帖子 ...

最新文章

  1. JSONObject没有fromObject方法(Json lib 库的使用)
  2. c语言双链表是什么意思,双链表的表示和实现(C语言)
  3. Java GridBagConstraints的帮助类:GBC
  4. 流程展示 php,js实现动态的流程进度展示条
  5. OpenShift 4 之Service Mesh教程(5)- 断路器Circuit Breaker
  6. Windows 环境变量设置工具
  7. java day48【 Maven 介绍 、 Maven 的使用 、Maven 常用命令 、 maven 工程运行调试 、总结】...
  8. SQL中常用的日期函数
  9. word2016+endnoteX7的安装与配置
  10. jvm如何排查生产环境cpu飙高的问题
  11. 可汗学院公开课: 统计学_1 统计学基本知识、二项及泊松分布
  12. 鸿蒙试炼如何拿经验,热血精灵派空空夜夜的勇士试炼 百万经验轻松得
  13. Linux软件更新时遇到的各种问题以及解决办法
  14. Mac无法识别硬盘解决办法
  15. 什么牌子的护眼灯对眼睛好?性价比最高的护眼灯
  16. 西北农林科技大学计算机系运动会,西北农林科技大学召开2018年学院春季运动会...
  17. Java之CompletableFuture异步、组合计算基本用法
  18. nodejs shell交互_NodeJs交互式命令行工具Inquirer.js-开箱指南
  19. 手机表格html5,手机上怎么做表格?
  20. 11 项目的工程文件存在哪里

热门文章

  1. java raster_Raster
  2. vue操作dom_vue源码全面解析(四十六)源码中操作DOM的方法集合
  3. opt文件夹下没有ros_ubuntu16.04下ROS操作系统学习笔记(二)
  4. 小学身高体重测试软件,学生身高、体重检测汇总分析
  5. Python动态变量名定义与调用
  6. mysql5.7 事件_MySQL 5.7新特性
  7. 性能不同的服务器可以组成云,多个服务器组成云
  8. 基于栅格地图的粒子群算法_基于GMapping的栅格地图的构建
  9. 详解java中Thread类,线程和进程的基本区别,多线程的好处,线程的五个生命周期,主线程和IDEA创建的Monitor Ctrl-Break守护线程;优雅地终止线程。死锁的产生
  10. ffmpeg实现摄像头拉流_[FFmpeg] 如何通过实时摄像头帧图片生成 rtmp 直播流?