Java CAS操作与Unsafe类详解

 更新时间:2021年02月27日 09:50:36   作者:心悦君兮君不知-睿  
这篇文章主要介绍了Java CAS操作与Unsafe类的相关资料,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下

一、复习

计算机内存模型,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

以上就是Java CAS操作与Unsafe类详解的详细内容,更多关于Java CAS操作与Unsafe类的资料请关注脚本之家其它相关文章!

相关文章

  • Spring的连接数据库以及JDBC模板(实例讲解)

    Spring的连接数据库以及JDBC模板(实例讲解)

    下面小编就为大家带来一篇Spring的连接数据库以及JDBC模板(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • IntelliJ IDEA 中必有得插件和配置

    IntelliJ IDEA 中必有得插件和配置

    这篇文章主要介绍了IntelliJ IDEA 中必有得插件和配置,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • Mybatis SqlSessionFactory与SqlSession详细讲解

    Mybatis SqlSessionFactory与SqlSession详细讲解

    SqlSessionFactory是MyBatis的核心类之一,其最重要的功能就是提供创建MyBatis的核心接口SqlSession,所以我们需要先创建SqlSessionFactory,为此我们需要提供配置文件和相关的参数
    2022-11-11
  • SpringBoot3实战教程之实现接口签名验证功能

    SpringBoot3实战教程之实现接口签名验证功能

    接口签名是一种重要的安全机制,用于确保 API 请求的真实性、数据的完整性以及防止重放攻击,这篇文章主要介绍了SpringBoot3实战教程之实现接口签名验证功能,需要的朋友可以参考下
    2025-04-04
  • SpringBoot-Admin实现微服务监控+健康检查+钉钉告警

    SpringBoot-Admin实现微服务监控+健康检查+钉钉告警

    本文主要介绍了SpringBoot-Admin实现微服务监控+健康检查+钉钉告警,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 关于HashMap 并发时会引起死循环的问题解析

    关于HashMap 并发时会引起死循环的问题解析

    JDK1.8之前采用头插,即在链表结构上每次都把数据放在链表头部。JDK1.8采用尾插方法,很多朋友在学习Java并发容器和框架时,看到为什么要使用ConcurrentHashMap时不知道究其原因,今天小编通过本文给大家介绍下HashMap 并发死循环问题,一起看看吧
    2021-05-05
  • 简单了解Java日志脱敏框架sensitive

    简单了解Java日志脱敏框架sensitive

    这篇文章主要介绍了简单了解Java日志脱敏框架sensitive,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • java判断对象中某个属性是否为空方法代码

    java判断对象中某个属性是否为空方法代码

    这篇文章主要给大家介绍了关于java判断对象中某个属性是否为空的相关资料,最近遇到后台接收值的时候,需要对接收对象进行非空校验,需要的朋友可以参考下
    2023-07-07
  • Java Lombok实现手机号码校验的示例代码

    Java Lombok实现手机号码校验的示例代码

    手机号码校验通常是系统开发中最基础的功能之一,本文主要介绍了Java Lombok实现手机号码校验的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Mybatis逻辑分页与物理分页PageHelper使用解析

    Mybatis逻辑分页与物理分页PageHelper使用解析

    这篇文章主要为大家介绍了Mybatis逻辑分页与物理分页PageHelper使用解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12

最新评论