Java多線程系列--“JUC原子類”04之 AtomicReference原子類


 

概要

本章對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篇)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM