资讯专栏INFORMATION COLUMN

AtomicReference、AtomicStampedReference、AtomicMarka

scq000 / 929人阅读

摘要:区别在于内部维护了一个的二元组。操作内部维护一个静态内部类表示引用对象表示时间戳版本号,型通过增加了版本号的操作,可以避免问题,即更新始终是递增的,不会出现往复。

这三个都是自JDK1.5开始加入到java.util.concurrent.atomic下面的。他们都可以在lock-free的情况下以原子的方式更新对象引用。

区别在于:AtomicStampedReference内部维护了一个[reference, integer] pairs的二元组。AtomicMarkableReference 内部维护了一个[reference, boolean] pairs的二元组。

以下部分源码片段摘自JDK1.8(保留了注释):

AtomicReference

</>复制代码

  1. public class AtomicReference implements java.io.Serializable {
  2. private static final long serialVersionUID = -1848883965231344442L;
  3. private static final Unsafe unsafe = Unsafe.getUnsafe();
  4. private static final long valueOffset;
  5. //class初始化时执行
  6. static {
  7. try {
  8. valueOffset = unsafe.objectFieldOffset
  9. (AtomicReference.class.getDeclaredField("value"));
  10. } catch (Exception ex) { throw new Error(ex); }
  11. }
  12. //通过volatile关键字保证value值的可见性。
  13. private volatile V value;
  14. public AtomicReference(V initialValue) {
  15. value = initialValue;
  16. }
  17. public AtomicReference() {
  18. }
  19. //CAS操作
  20. /**
  21. * Atomically sets the value to the given updated value
  22. * if the current value {@code ==} the expected value.
  23. * @param expect the expected value
  24. * @param update the new value
  25. * @return {@code true} if successful. False return indicates that
  26. * the actual value was not equal to the expected value.
  27. */
  28. public final boolean compareAndSet(V expect, V update) {
  29. return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
  30. }
  31. }

AtomicStampedReference

</>复制代码

  1. public class AtomicStampedReference {
  2. //内部维护一个静态内部类
  3. //reference表示引用对象
  4. //stamp表示时间戳(版本号),int型
  5. private static class Pair {
  6. final T reference;
  7. final int stamp;
  8. private Pair(T reference, int stamp) {
  9. this.reference = reference;
  10. this.stamp = stamp;
  11. }
  12. static Pair of(T reference, int stamp) {
  13. return new Pair(reference, stamp);
  14. }
  15. }
  16. private volatile Pair pair;
  17. /**
  18. * Creates a new {@code AtomicStampedReference} with the given
  19. * initial values.
  20. *
  21. * @param initialRef the initial reference
  22. * @param initialStamp the initial stamp
  23. */
  24. public AtomicStampedReference(V initialRef, int initialStamp) {
  25. pair = Pair.of(initialRef, initialStamp);
  26. }
  27. /**
  28. * Atomically sets the value of both the reference and stamp
  29. * to the given update values if the
  30. * current reference is {@code ==} to the expected reference
  31. * and the current stamp is equal to the expected stamp.
  32. *
  33. * @param expectedReference the expected value of the reference
  34. * @param newReference the new value for the reference
  35. * @param expectedStamp the expected value of the stamp
  36. * @param newStamp the new value for the stamp
  37. * @return {@code true} if successful
  38. */
  39. public boolean compareAndSet(V expectedReference,
  40. V newReference,
  41. int expectedStamp,
  42. int newStamp) {
  43. Pair current = pair;
  44. //通过增加了stamp(版本号)的CAS操作,可以避免ABA问题,即更新始终是递增的,不会出现往复。
  45. return
  46. expectedReference == current.reference &&
  47. expectedStamp == current.stamp &&
  48. ((newReference == current.reference &&
  49. newStamp == current.stamp) ||
  50. casPair(current, Pair.of(newReference, newStamp)));
  51. }
  52. private boolean casPair(Pair cmp, Pair val) {
  53. return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
  54. }
  55. }

AtomicMarkableReference

</>复制代码

  1. public class AtomicMarkableReference {
  2. //这里几乎和AtomicStampedReference相同,只是从 final int stamp 变成了 final boolean mark
  3. private static class Pair {
  4. final T reference;
  5. final boolean mark;
  6. private Pair(T reference, boolean mark) {
  7. this.reference = reference;
  8. this.mark = mark;
  9. }
  10. static Pair of(T reference, boolean mark) {
  11. return new Pair(reference, mark);
  12. }
  13. }
  14. private volatile Pair pair;
  15. /**
  16. * Creates a new {@code AtomicMarkableReference} with the given
  17. * initial values.
  18. *
  19. * @param initialRef the initial reference
  20. * @param initialMark the initial mark
  21. */
  22. public AtomicMarkableReference(V initialRef, boolean initialMark) {
  23. pair = Pair.of(initialRef, initialMark);
  24. }
  25. }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71176.html

相关文章

  • Java多线程进阶(十四)—— J.U.C之atomic框架:AtomicReference

    摘要:但是,有些操作会依赖于对象的变化过程,此时的解决思路一般就是使用版本号。在变量前面追加上版本号,每次变量更新的时候把版本号加一,那么就会变成。四的引入就是上面所说的加了版本号的。 showImg(https://segmentfault.com/img/remote/1460000016012188); 本文首发于一世流云的专栏:https://segmentfault.com/blo...

    aboutU 评论0 收藏0
  • 一文读懂 Java 中的原子类

    摘要:一无锁方案并发包中的原子类都是基于无锁方案实现的,相较于传统的互斥锁,无锁并没有加锁解锁线程切换的消耗,因此无锁解决方案的性能更好,同时无锁还能够保证线程安全。线程首先读取的值并加,如果此时有另一个线程更新了,则期望值和不相等,更新失败。 一、无锁方案 Java 并发包中的原子类都是基于无锁方案实现的,相较于传统的互斥锁,无锁并没有加锁、解锁、线程切换的消耗,因此无锁解决方案的性能更好...

    jas0n 评论0 收藏0
  • Java多线程学习(九)JUC 中的 Atomic 原子类总结

    摘要:即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。另外是一个变量,在内存中可见,因此可以保证任何时刻任何线程总能拿到该变量的最新值。 个人觉得这一节掌握基本的使用即可! 本节思维导图: showImg(https://segmentfault.com/img/remote/1460000016855442?w=1244&h=657); 1 Atomic 原子类介绍...

    Youngs 评论0 收藏0
  • java.util.concurrent.atomic包

    摘要:中的类可以分成组标量类,,,数组类,,更新器类,,复合变量类,第一组内部实现使用高效的方式和方法,从而避免了的高开销,执行效率大为提升。第二组内部并不是像一样维持一个变量,而是全部由方法实现。第四组给数据加版本信息,解决问题。 java.util.concurrent.atomic中的类可以分成4组: 标量类:AtomicBoolean,AtomicInteger,AtomicLong...

    zhangqh 评论0 收藏0
  • 高并发 - 基础

    摘要:异步非阻塞方式,任务的完成的通知由其他线程发出。并发并行死锁饥饿活锁死锁线程持有,线程持有。如等,在多线程情况下,该操作不是原子级别的而是原子的,所以一般用于状态标记。 同步/异步、阻塞/非阻塞 同步/异步是 API 被调用者的通知方式。阻塞/非阻塞则是 API 调用者的等待方式(线程挂机/不挂起)。 同步非阻塞 Future方式,任务的完成要主线程自己判断。如NIO,后台有多个任务在...

    phpmatt 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<