java 多线程系列---JUC原子类(四)之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()实际上是调用"=="去比较两个对象,即比较两个对象的地址是否相等。
转载:http://www.cnblogs.com/skywang12345/p/3514623.html
java 多线程系列---JUC原子类(四)之AtomicReference原子类的更多相关文章
- Java多线程系列--“JUC原子类”02之 AtomicLong原子类
概要 AtomicInteger, AtomicLong和AtomicBoolean这3个基本类型的原子类的原理和用法相似.本章以AtomicLong对基本类型的原子类进行介绍.内容包括:Atomic ...
- Java多线程系列--“JUC原子类”03之 AtomicLongArray原子类
概要 AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray这3个数组类型的原子类的原理和用法相似.本章以AtomicLongArray对数 ...
- Java多线程系列--“JUC原子类”04之 AtomicReference原子类
概要 本章对AtomicReference引用类型的原子类进行介绍.内容包括:AtomicReference介绍和函数列表AtomicReference源码分析(基于JDK1.7.0_40)Atomi ...
- Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类
概要 AtomicIntegerFieldUpdater, AtomicLongFieldUpdater和AtomicReferenceFieldUpdater这3个修改类的成员的原子类型的原理和用法 ...
- java 多线程系列---JUC原子类(三)之AtomicLongArray原子类
AtomicLongArray介绍和函数列表 在"Java多线程系列--“JUC原子类”02之 AtomicLong原子类"中介绍过,AtomicLong是作用是对长整形进行原子操 ...
- Java多线程系列--“JUC线程池”05之 线程池原理(四)
概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
- Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock
本章对ReentrantLock包进行基本介绍,这一章主要对ReentrantLock进行概括性的介绍,内容包括:ReentrantLock介绍ReentrantLock函数列表ReentrantLo ...
- Java多线程系列--“JUC锁”01之 框架
本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--“JUC锁”01之 框架02. Java多线程系列--“JUC锁”02之 互斥锁Reentrant ...
随机推荐
- Ubuntu 16.04 安装 RabbitMQ
Ubuntu 16.04 安装 RabbitMQ(注意,服务器安全组需要添加15672 和5672端口) #1 更新 $ sudo apt-get update$ sudo apt-get upgra ...
- Qt之密码框不可全选、复制、粘贴无右键菜单等
转载---> http://blog.sina.com.cn/s/blog_a6fb6cc90101artk.html 在做用户登录界面的时候,往往会用到密码框,则其中的一些功能也要求与普通的输 ...
- Qt QSortFilterProxyModel示例代码, 使用方法
1. QSortFilterProxyModel不能单独使用,它只是一个"代理",真正的数据需要另外的一个model提供,而且它是用来排序和过滤的. 2. 实现代码 #ifndef ...
- Python之print语句Python的注释
话不多说直接切入正题 print语句可以向屏幕上输出指定的文字.比如输出'hello, world',用代码实现如下: >>> print 'hello, world' 注意: 1. ...
- django 之补充
在dos命令行中输入 pip 如下命令进行安装: 安装最新的版本的 Django 命令如下: pip install django 安装 指定版本的 Django 命令如下: ...
- MySQL数据copy
摘自http://database.51cto.com/art/201011/234776.htm 1. 下面这个语句会拷贝表结构到新表newadmin中. (不会拷贝表中的数据) CREATE TA ...
- XE8_TPaintBox画
1. procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas); var bitmap :TBitMap; pt1, pt2 ...
- rsync工具
rsync工具 一.介绍 1.可以实现 本地数据 <----------> 远程数据/本地数据 的传输 2.两种通信方式(man rsync) (1)remote shell(一个冒号 ...
- 《Think in Java》(六)访问权限控制
类访问权限:public,default(包访问权限的类,在包外可以调用该类的static成员) 类属性访问权限:public,protected,default,private
- MySQL InnoDB与MyISAM存储引擎差异
言: 之前简单介绍过 MySQL 常用的存储引擎,今天对两个主流的存储简单分析下差异,书上没有参考的笔试题解答注解: 差异: MyISAM 只支持表锁,不支持事务,表损坏率较高.较老的存储引擎. ...