本文转载自:http://www.cnblogs.com/skywang12345/p/3514623.html

概要

本章对AtomicReference引用类型的原子类进行介绍。内容包括:

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()实际上是调用"=="去比较两个对象,即比较两个对象的地址是否相等。

【java】AtomicReference介绍的更多相关文章

  1. Android下HelloWorld项目的R.java文件介绍

    R.java文件介绍 HelloWorld工程中的R.java文件 package com.android.hellworld; public final class R {     public s ...

  2. 深入Java虚拟机读书笔记第一章Java体系结构介绍

    第1章 Java体系结构介绍 Java技术核心:Java虚拟机 Java:安全(先天防bug的设计.内存).健壮.平台无关.网络无关(底层结构上,对象序列化和RMI为分布式系统中各个部分共享对象提供了 ...

  3. java集合介绍(List,Set,Map)

    前言 介绍java的常用集合+各个集合使用用例 欢迎转载,请注明作者和出处哦☺ 参考: 1,<Java核心编程技术(第二版)> 2, http://www.cnblogs.com/Litt ...

  4. Java学习介绍

    Java版本介绍 JavaME:微型版,用于开发小型设备.智能卡.移动终端应用(使用率较低) JavaSE:标准版,用于创建桌面应用(企业用JavaSE创建桌面应用较少) JavaEE:企业版,用于创 ...

  5. 流行的9个Java框架介绍: 优点、缺点等等

    流行的9个Java框架介绍: 优点.缺点等等 在 2018年,Java仍然是世界上最流行的编程语言.它拥有一个巨大的生态系统,在全世界有超过900万Java开发人员.虽然Java不是最直接的语言,但是 ...

  6. Java监控工具介绍,VisualVm ,JProfiler,Perfino,Yourkit,Perf4J,JProbe,Java微基准测试【转】

    Java监控工具介绍,VisualVm ,JProfiler,Perfino,Yourkit,Perf4J,JProbe,Java微基准测试[转] 本文是本人前一段时间做一个简单Java监控工具调研总 ...

  7. java JNI介绍

    java JNI介绍 目录 java JNI介绍 1. Java调用C++代码 2.C++代码调用java代码 JNI是Java Native Interface的全称. oracle文档中是这样描述 ...

  8. Java秘诀!Java逻辑运算符介绍

    运算符丰富是 Java 语言的主要特点之一,它提供的运算符数量之多,在高级语言中是少见的. Java 语言中的运算符除了具有优先级之外,还有结合性的特点.当一个表达式中出现多种运算符时,执行的先后顺序 ...

  9. Java秘诀!Java赋值运算符介绍

    运算符丰富是 Java 语言的主要特点之一,它提供的运算符数量之多,在高级语言中是少见的. Java 语言中的运算符除了具有优先级之外,还有结合性的特点.当一个表达式中出现多种运算符时,执行的先后顺序 ...

随机推荐

  1. 第十八章 MySQL Workbench5.2使用(待续)

    ··········

  2. day6心得

    面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法.     引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思 ...

  3. 让你的javascript代码高大上

    1,创造简短的写法 你可以这么写: var slice = Array.prototype.slice; slice.call(arguments); //转化成数组 也可以这么写:(ie9+) va ...

  4. leetcode884

    class Solution { public: void SplitString(const string& s, vector<string>& v, const st ...

  5. Spring 快速入门

    1.持久层 (1) 域模型层   (2) Dao 持久层接口  (3) DaoImpl 持久层接口实现 2.业务层 Service 业务接口层 ServiceImpl  业务接口实现 3.展现层 Sp ...

  6. PHP下生成非重复的id

    PHP在多进程运行的情况下,如果不采用内存锁或者文件锁,基本没办法能解决生成唯一Id的问题.试过了静态变量.单例模式等等.查询到php里的uniqid()函数,最后还是找到了一个折中方式,虽然还是有可 ...

  7. shell编程之sed编辑器&gawk程序

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/560372 s ...

  8. linux中memset的正确用法

    linux中memset的正确用法 [起因]希望对各种类型的数组进行初始化,避免野值 [函数头文件] 提示:在linux中可以在terminal中输入 "man memset"进行 ...

  9. 老外畅想C# 5.0这个可以有

    C# 5.0 - not quite there yet! 老外大胆的YY了一下,感觉挺有意思转发过来. 回顾C#发展的历史,C#1.0模仿了Java,并保留了C/C++的一些特性如struct,新学 ...

  10. 十二.filter

    Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是 ...