当前位置: 首页 > news >正文

CAS之AtomicReference原理解析

如果你了解了AtomicInteger的工作原理,或者看了如下文章,知道了AtomicInteger只能对当个int类型共享变量做cas的缺点。

CAS之AtomicInteger原理解析_z275598733的博客-CSDN博客

那么AtomicReference就是来解决这个问题的。原理很类似,只是AtomicReference是对对象做cas操作。从一段AtomicReference类的方法调用代码开始来对源码做分析

public class Test {public static void main(String[] args) {A a1 = new A(0, 0l);A a2 = new A(1, 1l);AtomicReference<A> ar = new AtomicReference<>(a1);ar.getAndSet(a2);System.out.println(ar.get().toString());//打印对象ai的内存结构,需要引入jol-core工具包ClassLayout classLayout = ClassLayout.parseInstance(ar);System.out.println(classLayout.toPrintable());}
}@Getter
@Setter
@AllArgsConstructor
@ToString
class A{private int v1;private double v2;
}

从 new AtomicReference<>(a1)进入先看静态代码块和构造方法,再看 ar.getAndSet(a2) 做了什么。

public class AtomicReference<V> implements java.io.Serializable {...static {try {valueOffset = unsafe.objectFieldOffset(AtomicReference.class.getDeclaredField("value"));} catch (Exception ex) { throw new Error(ex); }}//与AtomicInterger类基本一致,只不过类型由int变成了泛型Vprivate volatile V value;public AtomicReference(V initialValue) {value = initialValue;}//与对象public final boolean compareAndSet(V expect, V update) {//this-当前AtomicReference对象;valueoffest-相对AtomicReference的内存偏移量;expectreturn unsafe.compareAndSwapObject(this, valueOffset, expect, update);}//具体实现,需要进入到Unsafe类中public final V getAndSet(V newValue) {this-当前AtomicReference对象;valueoffest-相对this对象的内存偏移量;newValue-新对象return (V)unsafe.getAndSetObject(this, valueOffset, newValue);}...
}

 进入到Unsafe.getAndSetObject方法中

public final class Unsafe {...public final Object getAndSetObject(Object var1, long var2, Object var4) {Object var5;do {//通过对象中value相对偏移量获取内存中的value对象,这里var5对其他线程是可见的, 如果不可见,那么这个值的获取就可能非内存真实值。与Unsafe.getAndAddInt异曲同工var5 = this.getObjectVolatile(var1, var2);//compareAndSwapObject的过程是原子性的,将重新获取到的内存对象value与var5比较,true则说明对象value并未被修改,可以将原对象改成var4。区别于Unsafe.compareAndSwapInt, 这里比较对象} while(!this.compareAndSwapObject(var1, var2, var5, var4));return var5;}//native方法,暂不深究public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);...
}

 以下是debug的信息

 AtomicReference类对象ar的内存结构

 总而言之,AtomicReference可以保证对象的修改是线程安全的,AtomicReference对比AtomicInteger 可以在共享对象内部维护多个共享变量,但是ABA问题依然没有解决。

http://www.lryc.cn/news/110184.html

相关文章:

  • JS/JQ实现字符串加密成 HEX(十六进制) 字符串
  • 骨传导耳机怎么样?盘点五款适合室外佩戴的骨传导耳机
  • 【flink】使用flink-web-ui提交作业报错
  • 「从零入门推荐系统」22:chatGPT、大模型在推荐系统中的应用
  • 机器学习---概述(一)
  • 概念解析 | AutoFed:面向异构数据的联邦多模态自动驾驶的学习框架
  • vue3+uniapp自定义tabbar
  • stable diffusion webui 安装
  • csdn文章编辑器必备语法备用
  • 机器学习鲁棒性笔记
  • ubuntu 有 1 个软件包没有被完全安装或卸载
  • 【QT调用ST-link-使用QT编写程序-调用ST-LINK_CLI.exe-烧写STM32F4xxx-基础样例】
  • 高并发下的Java项目解决方案
  • 华为推出手机系统云翻新服务:什么是云翻新?如何使用?
  • 修改时间和创建时间的设计问题
  • CentOS 搭建 Harbor 镜像仓库(图文详解)
  • 【云原生】k8s组件架构介绍与K8s最新版部署
  • 你真的了解什么是生成式AI吗?
  • Linux--高级IO
  • 【C# 基础精讲】C# 开发环境搭建(Visual Studio等)
  • 谷粒商城第九天-解决商品品牌问题以及前后端使用检验框架检验参数
  • Java8函数式接口
  • .Net6 Web Core API --- Autofac -- AOP
  • RocketMQ基本概念和高级原理
  • 小白到运维工程师自学之路 第六十六集 (docker 网络模型)
  • Go和Java实现建造者模式
  • AutoSAR系列讲解(实践篇)11.6-服务映射(自顶向下)
  • EXCEL, 用if({1,0,0} ...) 实现把给定的区域,输出为任意你想要的矩阵,数组区域!
  • c++实现Qt对象树机制
  • 骨传导蓝牙耳机排行榜,精选五款排名最靠前的耳机