您现在的位置是:首页 > 文章详情

java源码-AtomicReference

日期:2018-08-09点击:324

开篇

The AtomicReference class provides reference objects that may be read and written atomically, so when multiple threads try to reach them at the same time, only one will be able to do so.
换句话说就是AtomicReference提供Object对象的原子类操作,提供了更加灵活的操作


AtomicReference类和构造器

AtomicReference的构造函数类构造器有两个:

  • 无参构造函数采用默认值初始化为0
  • 有参数构造函数直接用initialValue来value的

AtomicReference类变量需要注意的两个点:

  • AtomicReference的关键逻辑在于static代码快中通过unsafe接口初始化value的内存地址,后续直接通过内存地址进行操作。
  • AtomicReference的value是用volatile进行修饰保证变量的可见性
public class AtomicReference<V> implements java.io.Serializable { private static final long serialVersionUID = -1848883965231344442L; private static final Unsafe unsafe = Unsafe.getUnsafe(); // 保存AtomicLong中value的内存地址便于快速操作 private static final long valueOffset; // 获取value的内存地址的逻辑操作 static { try { valueOffset = unsafe.objectFieldOffset (AtomicReference.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } private volatile V value; // 以传入的initialValue初始化value对象 public AtomicReference(V initialValue) { value = initialValue; } // 以传入的null初始化value对象 public AtomicReference() { } } 


AtomicReference的get操作

AtomicReference的get操作相比之前的AtomicLong的get操作少了getAndIncrement()等自增自减的操作,只支持整个对象的更新。

  • getAndSet()方法取出原来的值并更新新值newValue
  • getAndUpdate()、getAndAccumulate()等操作通过compareAndSet()操作完成原子性的对象更新
 public final V get() { return value; } @SuppressWarnings("unchecked") public final V getAndSet(V newValue) { return (V)unsafe.getAndSetObject(this, valueOffset, newValue); } public final V getAndUpdate(UnaryOperator<V> updateFunction) { V prev, next; do { prev = get(); next = updateFunction.apply(prev); } while (!compareAndSet(prev, next)); return prev; } public final V getAndAccumulate(V x, BinaryOperator<V> accumulatorFunction) { V prev, next; do { prev = get(); next = accumulatorFunction.apply(prev, x); } while (!compareAndSet(prev, next)); return prev; } 


AtomicReference的set操作

AtomicReference的set操作是通过unsafe.compareAndSwapObject()方法实现原子性操作,updateAndGet()方法只有在原子性更新成功后才能返回更新后的对象。

 public final void set(V newValue) { value = newValue; } public final void lazySet(V newValue) { unsafe.putOrderedObject(this, valueOffset, newValue); } public final boolean compareAndSet(V expect, V update) { return unsafe.compareAndSwapObject(this, valueOffset, expect, update); } public final boolean weakCompareAndSet(V expect, V update) { return unsafe.compareAndSwapObject(this, valueOffset, expect, update); } public final V updateAndGet(UnaryOperator<V> updateFunction) { V prev, next; do { prev = get(); next = updateFunction.apply(prev); } while (!compareAndSet(prev, next)); return next; } public final V accumulateAndGet(V x, BinaryOperator<V> accumulatorFunction) { V prev, next; do { prev = get(); next = accumulatorFunction.apply(prev, x); } while (!compareAndSet(prev, next)); return next; } 


案例

// AtomicReferenceTest.java的源码 import java.util.concurrent.atomic.AtomicReference; public class AtomicReferenceTest { public static void main(String[] args){ // 创建两个Person对象,它们的id分别是101和102。 Person p1 = new Person(101); Person p2 = new Person(102); // 新建AtomicReference对象,初始化它的值为p1对象 AtomicReference ar = new AtomicReference(p1); // 通过CAS设置ar。如果ar的值为p1的话,则将其设置为p2。 ar.compareAndSet(p1, p2); Person p3 = (Person)ar.get(); System.out.println("p3 is "+p3); System.out.println("p3.equals(p1)="+p3.equals(p1)); } } class Person { volatile long id; public Person(long id) { this.id = id; } public String toString() { return "id:"+id; } } 运行结果 p3 is id:102 p3.equals(p1)=false 


文末彩蛋

高手是持续性自律,你是间歇式自虐

对高手而言 自律是一种生活方式 若只是间歇性的热血沸腾 不可能成功 很多工作拼的不是才华 而是持续和稳定 所以先把你的勤奋变成现在进行时吧! 剔除自我感动,也学会自我成全 工作、代码、写作、跑步,近乎苦行僧般的生活让我感到很踏实 
原文链接:https://yq.aliyun.com/articles/666328
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章