概要

本章对AtomicReference引用类型的原子类进行介绍。内容包括:
AtomicReference介绍和函数列表
AtomicReference源码分析(基于JDK1.7.0_40)
AtomicReference示例

转载请注明出处:http://www.cnblogs.com/skywang12345/p/3514623.html

AtomicReference介绍和函数列表

AtomicReference是作用是对"对象"进行原子操作。

AtomicReference函数列表

// 使用 null 初始值创建新的 AtomicReference。
AtomicReference()
// 使用给定的初始值创建新的 AtomicReference。
AtomicReference(V initialValue) // 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
boolean compareAndSet(V expect, V update)
// 获取当前值。
V get()
// 以原子方式设置为给定值,并返回旧值。
V getAndSet(V newValue)
// 最终设置为给定值。
void lazySet(V newValue)
// 设置为给定值。
void set(V newValue)
// 返回当前值的字符串表示形式。
String toString()
// 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
boolean weakCompareAndSet(V expect, V update)

AtomicReference源码分析(基于JDK1.7.0_40)

在JDK1.7.0_40中AtomicReference.java的源码如下:

public class AtomicReference<V>  implements java.io.Serializable {
private static final long serialVersionUID = -1848883965231344442L; // 获取Unsafe对象,Unsafe的作用是提供CAS操作
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset; static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicReference.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
} // volatile类型
private volatile V value; public AtomicReference(V initialValue) {
value = initialValue;
} public AtomicReference() {
} public final V get() {
return value;
} 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 getAndSet(V newValue) {
while (true) {
V x = get();
if (compareAndSet(x, newValue))
return x;
}
} public String toString() {
return String.valueOf(get());
}
}

说明
AtomicReference的源码比较简单。它是通过"volatile"和"Unsafe提供的CAS函数实现"原子操作。
(01) value是volatile类型。这保证了:当某线程修改value的值时,其他线程看到的value值都是最新的value值,即修改之后的volatile的值。
(02) 通过CAS设置value。这保证了:当某线程池通过CAS函数(如compareAndSet函数)设置value时,它的操作是原子的,即线程在操作value时不会被中断。

AtomicReference示例

// 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

结果说明
新建AtomicReference对象ar时,将它初始化为p1。
紧接着,通过CAS函数对它进行设置。如果ar的值为p1的话,则将其设置为p2。
最后,获取ar对应的对象,并打印结果。p3.equals(p1)的结果为false,这是因为Person并没有覆盖equals()方法,而是采用继承自Object.java的equals()方法;而Object.java中的equals()实际上是调用"=="去比较两个对象,即比较两个对象的地址是否相等。


更多内容

1. Java多线程系列--“JUC原子类”01之 框架

2. Java多线程系列--“JUC原子类”02之 AtomicLong原子类

3. Java多线程系列--“JUC原子类”03之 AtomicLongArray原子类

4. Java多线程系列目录(共xx篇)

Java多线程系列--“JUC原子类”04之 AtomicReference原子类的更多相关文章

  1. Java多线程系列--“JUC线程池”04之 线程池原理(三)

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...

  2. Java多线程系列 JUC线程池04 线程池原理解析(三)

    转载 http://www.cnblogs.com/skywang12345/p/3509954.html  https://blog.csdn.net/qq_22929803/article/det ...

  3. Java多线程系列--“JUC线程池”06之 Callable和Future

    概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...

  4. Java多线程系列--“JUC线程池”05之 线程池原理(四)

    概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...

  5. Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类

    概要 AtomicIntegerFieldUpdater, AtomicLongFieldUpdater和AtomicReferenceFieldUpdater这3个修改类的成员的原子类型的原理和用法 ...

  6. Java多线程系列--“JUC原子类”02之 AtomicLong原子类

    概要 AtomicInteger, AtomicLong和AtomicBoolean这3个基本类型的原子类的原理和用法相似.本章以AtomicLong对基本类型的原子类进行介绍.内容包括:Atomic ...

  7. Java多线程系列--“JUC原子类”03之 AtomicLongArray原子类

    概要 AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray这3个数组类型的原子类的原理和用法相似.本章以AtomicLongArray对数 ...

  8. java 多线程系列---JUC原子类(三)之AtomicLongArray原子类

    AtomicLongArray介绍和函数列表 在"Java多线程系列--“JUC原子类”02之 AtomicLong原子类"中介绍过,AtomicLong是作用是对长整形进行原子操 ...

  9. Java多线程系列--“JUC集合”04之 ConcurrentHashMap

    概要 本章是JUC系列的ConcurrentHashMap篇.内容包括:ConcurrentHashMap介绍ConcurrentHashMap原理和数据结构ConcurrentHashMap函数列表 ...

随机推荐

  1. modal的使用

    $modal是一个可以迅速创建模态窗口的服务,创建部分页,控制器,并关联他们 $modal仅有一个方法open(options) templateUrl:模态窗口的地址 template:用于显示ht ...

  2. SpringAOP代理报错问题

    public class BaseDataSyncPushJob implements StatefulJob{ /*** 日志 */ private static final Log LOG = L ...

  3. Codeforces 13C(DP)

    题意:给出一个数列长度小于5000,每次操作将数列中的数加1或减1,问最少需要多少步操作可以得到一个不降序列: 分析:可知最少的次数,一定是由原来的数据构成的(据说可以用反证法证),即有原来的数组成的 ...

  4. PCA降维

    http://blog.csdn.net/a784763307/article/details/17289317 这篇比较棒 openCV版 void PrintMatrix(CvMat *Matri ...

  5. Python 之 super & MRO (没有遇到过适用场景)

    WOW!!! 这里wow的是真尼玛绕且没看完, 好困呐,贴上网址,等自己英文好一点再看(https://rhettinger.wordpress.com/2011/05/26/super-consid ...

  6. OpenCv编程

    (1)用OpenCv加载.显示.保存图片: //加载图片 IplImage* m_img;//定义IplImage格式的图片头指针: m_img=cvLoadImage(m_imgLoc);//装载m ...

  7. IOS9 新加关键字 nullable、nonnull、null_unspecified、null_resettable

    #import "ViewController.h" @interface ViewController () @property(nonatomic,nullable)NSStr ...

  8. LINQ LINQ Operators and Lambda Expression - Syntax & Examples

    LINQ is a cool feature in C# 3.0. Most of the developers are struggling for the syntax and examples. ...

  9. 原生Ajax封装随笔

    XMLHttpRequest 对象用于和服务器交换数据.我们使用 XMLHttpRequest 对象的 open() 和 send() 方法: open(method,url,async) metho ...

  10. windows10的激活及SQL Server 2008 的安装

    在我第一次安装的SQL Server的时候,由于我的电脑是windows8专业版未激活的系统,当时安装的时候,首先出现提示说我电脑缺少了某一个插件,于是乎就下了安装.但是后来又是安装不上,各种问题一一 ...