Java多线程系列---“JUC原子类”05之 AtomicReference原子类
转自:http://www.cnblogs.com/skywang12345/p/3514623.html(部分修改)
概要
本章对AtomicReference引用类型的原子类进行介绍。内容包括:
- AtomicReference介绍和函数列表
- AtomicReference源码分析(基于JDK1.7.0_40)
- 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的源码比较简单。它是通过"volatile"和"Unsafe提供的CAS函数实现"原子操作。
(01) value是volatile类型。这保证了:当某线程修改value的值时,其他线程看到的value值都是最新的value值,即修改之后的volatile的值。
(02) 通过CAS设置value。这保证了:当某线程池通过CAS函数(如compareAndSet函数)设置value时,它的操作是原子的,即线程在操作value时不会被中断。
1 package com.test.a; 2 3 //AtomicReferenceTest.java的源码 4 import java.util.concurrent.atomic.AtomicReference; 5 6 public class AtomicReferenceTest { 7 8 public static void main(String[] args) { 9 10 // 创建两个Person对象,它们的id分别是101和102。 11 Person p1 = new Person(101); 12 Person p2 = new Person(102); 13 // 新建AtomicReference对象,初始化它的值为p1对象 14 AtomicReference ar = new AtomicReference(p1); 15 // 通过CAS设置ar。如果ar的值为p1的话,则将其设置为p2。 16 ar.compareAndSet(p1, p2); 17 18 Person p3 = (Person) ar.get(); 19 System.out.println("p3 is " + p3); 20 System.out.println("p3.equals(p1)=" + p3.equals(p1)); 21 } 22 } 23 24 class Person { 25 volatile long id; 26 27 public Person(long id) { 28 this.id = id; 29 } 30 31 public String toString() { 32 return "id:" + id; 33 } 34 }
1 p3 is id:102 2 p3.equals(p1)=false
结果说明:
新建AtomicReference对象ar时,将它初始化为p1。
紧接着,通过CAS函数对它进行设置。如果ar的值为p1的话,则将其设置为p2。
最后,获取ar对应的对象,并打印结果。p3.equals(p1)的结果为false,这是因为Person并没有覆盖equals()方法,而是采用继承自Object.java的equals()方法;而Object.java中的equals()实际上是调用"=="去比较两个对象,即比较两个对象的地址是否相等。
(note:p2 equasl p3==true)