1. public class Snippet {
  2. //修改的是AtomicStampedReference对象里面的值了。
  3. public static void main(String[] args) {
  4. //现在AtomicStampedReference里面的pair是{aaa,1},
  5. AtomicStampedReference<String> reference = new AtomicStampedReference<String>("aaa",);
  6. System.out.println(reference.compareAndSet("aaa","bbb",reference.getStamp(),reference.getStamp()+));
  7. //现在AtomicStampedReference里面的pair是{bbb,2},
  8. System.out.println("reference.getReference() = " + reference.getReference());
  9.  
  10. //只是修改版本,不修改值,现在AtomicStampedReference里面的pair是{bbb,3},
  11. boolean b = reference.attemptStamp("bbb", reference.getStamp() + );
  12. System.out.println("b: "+b);
  13. System.out.println("reference.getStamp() = "+reference.getStamp());
  14.  
  15. boolean c = reference.weakCompareAndSet("bbb","ccc",, reference.getStamp()+);
  16. System.out.println("reference.getReference() = "+reference.getReference());
  17. System.out.println("c = " + c);//现在AtomicStampedReference里面的pair是{bbb,3},
  18. }
  19. }
  1. public class AtomicStampedReference<V> {
  2.  
  3. private static class Pair<T> {//将值和版本号封装为一个Pair,比较就是比较这个Pair。
  4. final T reference;
  5. final int stamp;
  6. private Pair(T reference, int stamp) {
  7. this.reference = reference;
  8. this.stamp = stamp;
  9. }
  10. static <T> Pair<T> of(T reference, int stamp) {
  11. return new Pair<T>(reference, stamp);
  12. }
  13. }
  14.  
  15. private volatile Pair<V> pair;//多个线程同时修改这个pair要可见。比如:一直自加到100
  16.  
  17. public AtomicStampedReference(V initialRef, int initialStamp) {//构造AtomicStampedReference时候把要多线程修改的
  18. //值封装成pair
  19. pair = Pair.of(initialRef, initialStamp);
  20. }
  21.  
  22. public V getReference() {//获取准备通过AtomicStampedReference来改变的值。
  23. return pair.reference;
  24. }
  25.  
  26. public int getStamp() {//获取准备通过AtomicStampedReference来改变的值的版本号。
  27. return pair.stamp;
  28. }
  29.  
  30. public V get(int[] stampHolder) {
  31. Pair<V> pair = this.pair;
  32. stampHolder[] = pair.stamp;
  33. return pair.reference;
  34. }
  35.  
  36. public boolean weakCompareAndSet(V expectedReference,
  37. V newReference,
  38. int expectedStamp,
  39. int newStamp) {
  40. return compareAndSet(expectedReference, newReference,
  41. expectedStamp, newStamp);
  42. }
  43. //旧值修改为新值。有3个:现在值2个,期望现在值2个,新值2个。
  44. //期望值和现在值2个相等,前提下,新值和现在值2个都相等不改变,否则该变。
  45. public boolean compareAndSet(V expectedReference,
  46. V newReference,
  47. int expectedStamp,
  48. int newStamp) {
  49. Pair<V> current = pair;
  50. return
  51. //现在值和期望现在值里面2个一样直接返回false不需要更新。
  52. expectedReference == current.reference &&
  53. expectedStamp == current.stamp &&
  54. //现在值和期望现在值里面2个一样需要更新
  55. //新值和现在值2个都一样返回false不需要更新
  56. ((newReference == current.reference &&
  57. newStamp == current.stamp) ||
  58. //现在值和期望现在值里面2个一样,并且新值和现在值有一个不一样,需要更新。
  59. casPair(current, Pair.of(newReference, newStamp)));//改变旧的pair为新的pair,新的pair要重新构造一个新的。
  60. }
  61.  
  62. public void set(V newReference, int newStamp) {
  63. Pair<V> current = pair;
  64. if (newReference != current.reference || newStamp != current.stamp)
  65. this.pair = Pair.of(newReference, newStamp);
  66. }
  67.  
  68. public boolean attemptStamp(V expectedReference, int newStamp) {
  69. Pair<V> current = pair;
  70. return
  71. expectedReference == current.reference &&
  72. (newStamp == current.stamp ||
  73. casPair(current, Pair.of(expectedReference, newStamp)));
  74. }
  75.  
  76. // Unsafe mechanics
  77.  
  78. private static final sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe();
  79. private static final long pairOffset =
  80. objectFieldOffset(UNSAFE, "pair", AtomicStampedReference.class);
  81.  
  82. private boolean casPair(Pair<V> cmp, Pair<V> val) {
  83. return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);//改变里面的pair从cmp到val
  84. }
  85.  
  86. static long objectFieldOffset(sun.misc.Unsafe UNSAFE,
  87. String field, Class<?> klazz) {
  88. try {
  89. return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field));
  90. } catch (NoSuchFieldException e) {
  91. // Convert Exception to corresponding Error
  92. NoSuchFieldError error = new NoSuchFieldError(field);
  93. error.initCause(e);
  94. throw error;
  95. }
  96. }
  97. }

AtomicStampedReference源码分析的更多相关文章

  1. 死磕 java并发包之AtomicStampedReference源码分析(ABA问题详解)

    问题 (1)什么是ABA? (2)ABA的危害? (3)ABA的解决方法? (4)AtomicStampedReference是什么? (5)AtomicStampedReference是怎么解决AB ...

  2. AtomicStampedReference 源码分析

    AtomicStampedReference AtomicStampedReference 能解决什么问题?什么时候使用 AtomicStampedReference? 1)AtomicStamped ...

  3. AtomicInteger源码分析——基于CAS的乐观锁实现

    AtomicInteger源码分析——基于CAS的乐观锁实现 1. 悲观锁与乐观锁 我们都知道,cpu是时分复用的,也就是把cpu的时间片,分配给不同的thread/process轮流执行,时间片与时 ...

  4. Java高并发之无锁与Atomic源码分析

    目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntege ...

  5. 并发-AtomicInteger源码分析—基于CAS的乐观锁实现

    AtomicInteger源码分析—基于CAS的乐观锁实现 参考: http://www.importnew.com/22078.html https://www.cnblogs.com/mantu/ ...

  6. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  7. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  8. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  9. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

随机推荐

  1. ko.js学习一

    一.KO是一个MVVM框架 声明式绑定 (Declarative Bindings):使用简明易读的语法很容易地将模型(model)数据关联到DOM元素上. UI界面自动刷新 (Automatic U ...

  2. __x__(25)0907第四天__ overflow 父元素对溢出内容的处理

    overflow    父元素对于溢出内容的处理 visible;    默认值,对于溢出内容,在父元素之外显示. hidden;    对于溢出内容,进行隐藏,不显示. scroll;    对于溢 ...

  3. 超小Web手势库AlloyFinger原理(转载)

    目前AlloyFinger作为腾讯手机QQ web手势解决方案,在各大项目中都发挥着作用. 感兴趣的同学可以去Github看看: https://github.com/AlloyTeam/AlloyF ...

  4. larave异步多图片上传的实现和注意事项及$file的对象函数

    要使用多图片上传,首先要在input添加multipart,同时注意name的参数要加[],不然,不算是数组.具体如下,注意绿色地方.如果是单张图片,把[]去掉,不要multiple; <inp ...

  5. Java程序生成一个Access文件

    package access; import java.io.File;import java.io.IOException;import java.sql.SQLException;import j ...

  6. Selenium 3 学习小结

    4个类+常用的46个方法 从以下知识内容对selenium 3自动化框架进行初步学习: 1.安装selenium pip install selenium pip list 2.驱动.关闭浏览器 首先 ...

  7. 旧版本的firefox 下载 和 安装(查找web元素路径) ---web 元素 自动化测试

    ftp.mozilla.orgpubfirefoxreleases   旧版下载地址   选择47版本     因为48后面的会进行插件校验    这样firepath安装不成功   安装文件:在百度 ...

  8. SNMP 优秀帖子

    -- 比较系统的描述http://blog.sina.com.cn/s/blog_54837cf301011607.html 几个SNMP官方网站(搜索关键字:snmplibrary C#):http ...

  9. python摸爬滚打之----tcp协议的三次握手四次挥手

    TCP协议的三次握手, 四次挥手 三次握手过程 1, 服务器时刻准备接受客户端进程的连接请求, 此时服务器就进入了LISTEN(监听)状态; 2, 客户端进程然后向服务器发出连接请求报文, 之后客户端 ...

  10. python numpy库的基本内容

    import numpy as np np.getfromtxt("路径",delimiter = "," ,dtype = str)  #读取txt文件数据 ...