Java CAS操作与Unsafe类详解

作者:心悦君兮君不知-睿 时间:2023-06-15 10:06:49 

目录
  • 一、复习

  • 二、两者对比

  • 三、在什么情况下才会使用volatile

  • 四、Java中的原子性操作

  • 五、Java中的CAS操作

  • 六、ABA问题

  • 七、Unsafe类

    • 1.long objectFieldOffset(Field field)

    • 2.int arrayBaseOffset(Class arrayClass)

    • 3.int arrayIndexOffset(Class arrayClass)

    • 4.boolean compareAndSwapLong(Object obj,long offset,long expect,long update)

  • 八、源码:

    一、复习

    计算机内存模型,synchronized和volatile关键字简介

    二、两者对比

    sychronized和volatile都解决了内存可见性问题
    不同点:
    (1)前者是独占锁,并且存在者上下文切换的开销以及线程重新调度的开销;后者是非阻塞算法,不会造成上下文切换的开销。
    (2)前者可以保证操作的原子性,但是后者不能保证操作的原子性。

    三、在什么情况下才会使用volatile

    • 写入变量是不依赖当前值的,如果是依赖当前值的话,由于获取-计算-写入,三者不是原子性操作,而volatile是保证原子性操作的。

    • 变量没有加锁的时候,如果变量加锁了,是可以保证内存的可见性的因此不需要再使用volatile

    四、Java中的原子性操作

    • 原子性操作通俗的来讲就是一组操作,要么都执行成功,要么都执行失败,不存在执行部分成功的情况

    • 使用synchronized关键字既可以保证操作的原子性又可以保证内存的可见性,volatile只能保证内存的可见性,但是不能保证操作的原子性;synchronized固然好,但在高并发的情况下,由于它是一种独占锁,因此会引起性能低下的问题。

    五、Java中的CAS操作

    • 定义:CAS(compare and swap)比较并交换,这是JDK提供的一种非阻塞算法,它通过硬件保证了比较-更新的原子性问题。JDK中的Unsafe类提供了一系列的compareAndSwap*方法,下面以compareAndSwapLong为例进行讲解

    • boolean compare(Object obj,long offset,long expect,long update)

    • 先分别解释一下各个参数,obj是一个对象的引用(也就是对象存储的地址),offset是相对于前面地址的偏移量,expect是一个预想的值,update代表如果和预想的值一样,那么就是使用update这个值来代替,并且返回true,否则返回false

    • 这是处理器提供的一种原子性指令

    六、ABA问题

    • 描述:线程1获取变量x的值为A,然后尝试修改为B,但是此时如果有另一个线程修改了x的值为B,同时又修改成了A,那么线程2的这个A和线程1之前的A就不是同一个A了

    • 产生原因:环形依赖,变量的值从A到B,然后又从B到A,这样只能一个方向轮转,如果是从A到B,然后从B到C就不会出现这种情况。

    • 解决方式:JDK中的AtomicStampedReferece给每个变量一个时间戳,从而避免了ABA问题

    七、Unsafe类

    在JDK中的rt.jar包中有许多方法都是native的,这是一种硬件级别的操作,使用JNI来调用C++底层函数来操作。

    1.long objectFieldOffset(Field field)

    释义:获取某个对象的中的某个域值所在对象的中的内存偏移量


    try{
     long value = Unsafe.objectFieldOffset(AutomicLong.class.getDeclaredField("value"));
    }catch(Exception e){
     e.printStackTrace();
    }

    2.int arrayBaseOffset(Class arrayClass)

    释义:获取数组中的第一个元素地址

    3.int arrayIndexOffset(Class arrayClass)

    释义:获取数组中第一个元素的字节大小

    4.boolean compareAndSwapLong(Object obj,long offset,long expect,long update)

    可以见上文

    八、源码:

    所在包:com.ruigege.OtherFoundationOfConcurrent2

    https://github.com/ruigege66/ConcurrentJava

    来源:https://www.cnblogs.com/ruigege0000/p/14028056.html

    标签:Java,CAS操作,Unsafe类
    0
    投稿

    猜你喜欢

  • Java Annotation注解相关原理代码总结

    2023-11-18 02:13:57
  • Android Camera开发实现可复用的相机组件

    2023-04-08 20:34:56
  • Java8 Comparator源码演示及解析

    2023-09-18 10:51:12
  • SpringBoot集成gRPC微服务工程搭建实践的方法

    2022-03-11 22:10:39
  • RocketMQ broker 消息投递流程处理PULL_MESSAGE请求解析

    2021-11-18 17:12:49
  • 解决使用json-lib包实现xml转json时空值被转为空中括号的问题

    2022-10-20 02:12:14
  • Spring定时任务中@PostConstruct被多次执行异常的分析与解决

    2022-08-20 07:28:22
  • Java实现将txt文件转成xls文件的方法

    2022-05-20 10:21:25
  • 我用java实现了王者荣耀的皮肤和英雄技能

    2022-01-13 13:44:09
  • Mac OS下为Android Studio编译FFmpeg解码库的详细教程

    2023-06-30 02:37:54
  • Mybatis Log Plugin的使用方式

    2021-08-27 19:02:31
  • Android自定义View画圆功能

    2023-05-18 10:47:24
  • Winform利用分页控件实现导出PDF文档功能

    2023-08-11 10:15:04
  • Spring Boot分离配置文件的多种方式总结

    2021-08-31 14:43:37
  • Java实现多线程大批量同步数据(分页)

    2021-12-18 17:41:18
  • springboot使用redis实现从配置到实战

    2023-05-05 09:49:08
  • Android笔记之:App应用之启动界面SplashActivity的使用

    2023-03-21 19:05:56
  • unity3D实现摄像机抖动特效

    2022-09-20 12:10:42
  • Java中局部变量和成员变量的区别详解

    2021-12-26 11:53:36
  • Android编程判断网络连接是否可用的方法

    2021-06-25 20:25:03
  • asp之家 软件编程 m.aspxhome.com