网站首页 > 文章精选 正文
AtomicStampedReference 类提供了对对象引用变量的原子读和写, AtomicStampedReference是指多个试图更改同一AtomicStampedReference的线程不会使AtomicStampedReference最终处于不一致的状态。
AtomicStampedReference 和AtomicReference 不一样的是,AtomicStampedReference在内部同时保留对象引用和数据戳,引用和数据戳可以通过compareAndSet()方法使用单CAS操作进行交换.
AtomicStampedReference设计是为了解决AtomicReference 不能解决的ABA问题,ABA问题后面会讲解。
创建AtomicStampedReference
创建 AtomicStampedReference实例:
Object initialRef = null;
int initialStamp = 0;
AtomicStampedReference atomicStampedReference =
new AtomicStampedReference(intialRef, initialStamp);
创建有类型的AtomicStampedReference
可以通过泛型创建指定类型的AtomicStampedReference,下面是代码:
String initialRef = null;
int initialStamp = 0;
AtomicStampedReference<String> atomicStampedReference =
new AtomicStampedReference<String>(
initialRef, initialStamp
);
创建了一个String类型的 AtomicStampedReference,如果知道引用的类型,一般建议使用AtomicStampedReference 时使用泛型。
获取AtomicStampedReference引用
可以通过AtomicStampedReference的getReference方法获取存储在AtomicStampedReference中的引用。如果不使用泛型,getReference()将返回Object对象的引用,如果使用了泛型,将返回创建AtomicStampedReference 变量时时候使用的泛型,下面是首先是不使用泛型 AtomicStampedReference 的getReference()例子:
String initialRef = "first text";
AtomicStampedReference atomicStampedReference = (String)
new AtomicStampedReference(initialRef, 0);
String reference = atomicStampedReference.getReference();
注意有必要将getReference()返回的引用强制转换为字符串,因为在AtomicStampedReference为非类型化时,getReference()将返回一个对象引用。
下面是使用泛型的AtomicStampedReference 例子:
String initialRef = "first text";
AtomicStampedReference<String> atomicStampedReference =
new AtomicStampedReference<String>(
initialRef, 0
);
String reference = atomicStampedReference.getReference();
注意,这儿不再需要使用强制类型转换,因为使用了泛型,在编译时候已经知道了返回的是String引用。
获取AtomicStampedReference的数据戳
AtomicStampedReference 同时还有一个getStamp() 方法,用来获取内部存储的数据戳,下面是代码:
String initialRef = "first text";
AtomicStampedReference<String> atomicStampedReference =
new AtomicStampedReference<>(initialRef, 0);
int stamp = atomicStampedReference.getStamp();
原子性获取引用和数据戳
AtomicStampedReference 可以通过一个简单的,原子操作get()方法同时获取到引用和数据戳,可以将int类型的数组作为参数传到get()方法,并返回引用类型,同时数据戳会存储在int类型数组的第一个元素,下面是代码:
String initialRef = "text";
String initialStamp = 0;
AtomicStampedReference<String> atomicStampedReference =
new AtomicStampedReference<>(
initialRef, initialStamp
);
int[] stampHolder = new int[1];
String ref = atomicStampedReference.get(stampHolder);
System.out.println("ref = " + ref);
System.out.println("stamp = " + stampHolder[0]);
Being able to obtain both reference and stamp as a single atomic operation is important for some types of concurrent algorithms.
设置AtomicStampedReference的引用
可以通过AtomicStampedReference实例的set()方法存储引用. 在没有使用 AtomicStampedReference实例的set()方法中第一个参数是使用的 Object对象引用,在使用泛型的 AtomicStampedReference的set()方法第一个参数是定义时的泛型类型,下面是
AtomicStampedReference 的set()代码:
AtomicStampedReference<String> atomicStampedReference =
new AtomicStampedReference<>(null, 0);
String newRef = "New object referenced";
int newStamp = 1;
atomicStampedReference.set(newRef, newStamp);
我们看到无论使不使用泛型的set()方法都没有什么区别,唯一的不一样是编译的时候应该控制了类型。
CAS操作AtomicStampedReference引用
AtomicStampedReference类包含了一个有用的 compareAndSet()方法, compareAndSet()方法将一个期望的引用与存储在 AtomicStampedReference实例中的值比较,如果引用与数据戳都相等(equals()或者 ==),那么 AtomicStampedReference实例将被设置为新的引用,compareAndSet()如果设置成功将返回ture否则返回false.下面是AtomicStampedReference 的compareAndSet()例子:
String initialRef = "initial value referenced";
int initialStamp = 0;
AtomicStampedReference<String> atomicStringReference =
new AtomicStampedReference<String>(
initialRef, initialStamp
);
String newRef = "new value referenced";
int newStamp = initialStamp + 1;
boolean exchanged = atomicStringReference
.compareAndSet(initialRef, newRef, initialStamp, newStamp);
System.out.println("exchanged: " + exchanged); //true
exchanged = atomicStringReference
.compareAndSet(initialRef, "new string", newStamp, newStamp + 1);
System.out.println("exchanged: " + exchanged); //false
exchanged = atomicStringReference
.compareAndSet(newRef, "new string", initialStamp, newStamp + 1);
System.out.println("exchanged: " + exchanged); //false
exchanged = atomicStringReference
.compareAndSet(newRef, "new string", newStamp, newStamp + 1);
System.out.println("exchanged: " + exchanged); //true
例子首先创建了 AtomicStampedReference,然后通过compareAndSet()设置引用和数据戳,第二次在调用 compareAndSet()没有成功,因为第一次的 initialRef 与存储值一样,这时内部存储的是newRef,所以在调用compareAndSet()失败。
第二段,首先initialStamp 与期望值newStamp 不一样更新失败,此时存储的为newStamp ,再次调用compareAndSet()则成功。
参考:
https://blog.csdn.net/cgsyck/article/details/108026037
http://tutorials.jenkov.com/java-util-concurrent/atomicstampedreference.html
http://tutorials.jenkov.com/java-concurrency/non-blocking-algorithms.html
http://tutorials.jenkov.com/java-generics/index.html
猜你喜欢
- 2025-05-10 【锁思想】自旋 or CAS 它俩真的一样吗?一文搞懂
- 2025-05-10 盘点JAVA中基于CAS实现的原子类(盘点java中基于cas实现的原子类是什么)
- 2025-05-10 Java并发 之 Atomic 原子操作类(java如何实现原子性)
- 2025-05-10 JDK源码剖析之AtomicStampedReference和AtomicMarkableReference
- 2025-05-10 Java并发工具:AtomicStampedReference
- 05-10【锁思想】自旋 or CAS 它俩真的一样吗?一文搞懂
- 05-10盘点JAVA中基于CAS实现的原子类(盘点java中基于cas实现的原子类是什么)
- 05-10Java并发 之 Atomic 原子操作类(java如何实现原子性)
- 05-10JDK源码剖析之AtomicStampedReference和AtomicMarkableReference
- 05-10java并发-AtomicStampedReference
- 05-10Java并发工具:AtomicStampedReference
- 05-1011款常用Java编程软件推荐(建议收藏)
- 05-10优秀程序员必用工具锦集(一款程序员必备的软件)
- 最近发表
-
- 【锁思想】自旋 or CAS 它俩真的一样吗?一文搞懂
- 盘点JAVA中基于CAS实现的原子类(盘点java中基于cas实现的原子类是什么)
- Java并发 之 Atomic 原子操作类(java如何实现原子性)
- JDK源码剖析之AtomicStampedReference和AtomicMarkableReference
- java并发-AtomicStampedReference
- Java并发工具:AtomicStampedReference
- 11款常用Java编程软件推荐(建议收藏)
- 优秀程序员必用工具锦集(一款程序员必备的软件)
- 《若依ruoyi》第一章:本地开发环境搭建
- 软件开发不可错过的6款必备工具(软件 开发工具)
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)