1. 程式人生 > >Java多線程系列---“JUC原子類”06之 AtomicLongFieldUpdater原子類

Java多線程系列---“JUC原子類”06之 AtomicLongFieldUpdater原子類

添加 bstr pro 源碼 set 當前 span value .com

轉自:http://www.cnblogs.com/skywang12345/p/3514635.html (含部分修改)

概要

AtomicIntegerFieldUpdater, AtomicLongFieldUpdater和AtomicReferenceFieldUpdater這3個修改類的成員的原子類型的原理和用法相似。本章以對基本類型的原子類進行介紹。內容包括:

  • AtomicLongFieldUpdater介紹和函數列表
  • AtomicLongFieldUpdater示例
  • AtomicLongFieldUpdater源碼分析(基於JDK1.7.0_40)

AtomicLongFieldUpdater介紹和函數列表

AtomicLongFieldUpdater可以對指定"類的 ‘volatile long‘類型的成員"進行原子更新。它是基於反射原理實現的。

AtomicLongFieldUpdater函數列表

// 受保護的無操作構造方法,供子類使用。
protected AtomicLongFieldUpdater()

// 以原子方式將給定值添加到此更新器管理的給定對象的字段的當前值。
long addAndGet(T obj, long delta)
// 如果當前值 == 預期值,則以原子方式將此更新器所管理的給定對象的字段設置為給定的更新值。
abstract boolean compareAndSet(T obj, long
expect, long update) // 以原子方式將此更新器管理的給定對象字段當前值減 1。 long decrementAndGet(T obj) // 獲取此更新器管理的在給定對象的字段中保持的當前值。 abstract long get(T obj) // 以原子方式將給定值添加到此更新器管理的給定對象的字段的當前值。 long getAndAdd(T obj, long delta) // 以原子方式將此更新器管理的給定對象字段當前值減 1。 long getAndDecrement(T obj) // 以原子方式將此更新器管理的給定對象字段的當前值加 1。 long getAndIncrement(T obj)
// 將此更新器管理的給定對象的字段以原子方式設置為給定值,並返回舊值。 long getAndSet(T obj, long newValue) // 以原子方式將此更新器管理的給定對象字段當前值加 1。 long incrementAndGet(T obj) // 最後將此更新器管理的給定對象的字段設置為給定更新值。 abstract void lazySet(T obj, long newValue) // 為對象創建並返回一個具有給定字段的更新器。 static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) // 將此更新器管理的給定對象的字段設置為給定更新值。 abstract void set(T obj, long newValue) // 如果當前值 == 預期值,則以原子方式將此更新器所管理的給定對象的字段設置為給定的更新值。 abstract boolean weakCompareAndSet(T obj, long expect, long update)

舉例說明:

技術分享圖片
 1 // LongTest.java的源碼
 2 import java.util.concurrent.atomic.AtomicLongFieldUpdater;
 3 
 4 public class LongFieldTest {
 5     
 6     public static void main(String[] args) {
 7 
 8         // 獲取Person的class對象
 9         Class cls = Person.class; 
10         // 新建AtomicLongFieldUpdater對象,傳遞參數是“class對象”和“long類型在類中對應的名稱”
11         AtomicLongFieldUpdater mAtoLong = AtomicLongFieldUpdater.newUpdater(cls, "id");
12         Person person = new Person(12345678L);
13 
14         // 比較person的"id"屬性,如果id的值為12345678L,則設置為1000。
15         mAtoLong.compareAndSet(person, 12345678L, 1000);
16         System.out.println("id="+person.getId());
17     }
18 }
19 
20 class Person {
21     volatile long id;
22     public Person(long id) {
23         this.id = id;
24     }
25     public void setId(long id) {
26         this.id = id;
27     }
28     public long getId() {
29         return id;
30     }
31 }
View Code

運行結果

id=1000

下面分析LongFieldTest.java的流程。

1. newUpdater()
newUpdater()的源碼如下:

復制代碼
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
    Class<?> caller = Reflection.getCallerClass();
    if (AtomicLong.VM_SUPPORTS_LONG_CAS)
        return new CASUpdater<U>(tclass, fieldName, caller);
    else
        return new LockedUpdater<U>(tclass, fieldName, caller);
}
復制代碼
說明:newUpdater()的作用是獲取一個AtomicIntegerFieldUpdater類型的對象。
它實際上返回的是CASUpdater對象,或者LockedUpdater對象;具體返回哪一個類取決於JVM是否支持long類型的CAS函數。CASUpdater和LockedUpdater都是AtomicIntegerFieldUpdater的子類,它們的實現類似。下面以CASUpdater來進行說明。

 

CASUpdater類的源碼如下:

public boolean compareAndSet(T obj, long expect, long update) {
    if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
    return unsafe.compareAndSwapLong(obj, offset, expect, update);
}
說明:它實際上是通過CAS函數操作。如果類的long對象的值是expect,則設置它的值為update。 

Java多線程系列---“JUC原子類”06之 AtomicLongFieldUpdater原子類