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未被捕获的异常在你学习在程序中处理异常之前,看一看如果你不处理它们会有什么情况发生是很有好处的。下面的小程序包括一个故意导致被零除错
- 本文实例为大家分享了Java实现生成n个不重复的随机数的具体代码,供大家参考,具体内容如下需求:根据min和max,生成n个不重复的随机数。
- 用过spring框架进行开发的人,多多少少会使用过它的AOP功能,都知道有@Before、@Around和@After等advice。最近,
- mybatis3中增加了使用注解来配置Mapper的新特性,本篇文章主要介绍其中几个@Provider的使用方式,他们是:@SelectPr
- 错误Mybatis-Plus (简称MP) 是mybatis的一个增强工具,在mybatis的基础上只做增强不做改变,简化了开发效率。其实就
- 在网络信息高速发展的今天,移动设备的方便快捷已经深入人心,越来越多的开发人员会选择在移动设备上查看或编辑源代码。于是,Android平台上大
- 首先在pom文件里引入mqtt的依赖配置<!--mqtt--> <d
- 需求介绍相信大家在请求接口的时候,很多时候都是需要传参的,除了业务必要的字段外,还有一些恒定不变的字段,包括一些用来编码的固定字段。这些固定
- 在安卓开发中,会碰到选开始日期和结束日期的问题。特别是在使用Pad时,如果弹出一个Dialog,能够同时选择开始日期和结束日期,那将是极好的
- FPS 每秒帧数背景消除建模 BSMBackground SUbtractionBS算法图像分割(GMM-高斯混合模型)机器学习(KNN-K
- 通常在写程序的时候,当要用到某些组件,采用的方法一般都是动态创建,用完以后就释放掉。Visual C#在程序运行的时
- 1. 前言本文主要是介绍一下RocketMQ消息生产者在发送消息的时候发送失败的问题处理?这里有两个点,一个是关于消息的处理,一个是关于br
- 前文传送门:Netty分布式高性能工具类同线程下回收对象解析异线程回收对象就是创建对象和回收对象不在同一条线程的情况下, 对象回收的逻辑我们
- AndroidManifest.xml <uses-feature>和<uses-permisstion>分析及比较
- final File imageFile = new File(getCacheDir().getPath() + "/img/&
- 一、Flow的基本概念Kotlin 的 Flow 相信大家都或多或少使用过,毕竟目前比较火,目前我把Flow的使用整理了一下。希望和大家所学
- 项目需要从其他网站获取数据,因为是临时加的需求,在开始项目时没想到需要多数据源于是百度了一下,发现只需要改动一下Spring 的applic
- 本文以C#为例讲解木马程序的实现过程。要实现木马服务的程序,主要实现以下几个功能:后台的运行(隐藏技术),控制码的接收与注册表的修改,下面就
- 一.并行LINQSystem.Linq名称空间中包含的类ParallelEnumerable可以分解查询的工作,使其分布在多个线程上。尽管E
- 1.@RequestMapping注解1.1@RequestMapping注解的功能从注解名称上我们可以看到,@RequestMapping