java原始碼-AtomicReference
開篇
The AtomicReference class provides reference objects that may be read and written atomically, so when multiple threads try to reach them at the same time, only one will be able to do so.
換句話說就是AtomicReference提供Object物件的原子類操作,提供了更加靈活的操作。
AtomicReference類和構造器
AtomicReference的建構函式類構造器有兩個:
- 無參建構函式採用預設值初始化為0
- 有引數建構函式直接用initialValue來value的
AtomicReference類變數需要注意的兩個點:
- AtomicReference的關鍵邏輯在於static程式碼快中通過unsafe介面初始化value的記憶體地址,後續直接通過記憶體地址進行操作。
- AtomicReference的value是用volatile進行修飾保證變數的可見性
public class AtomicReference<V> implements java.io.Serializable {
private static final long serialVersionUID = -1848883965231344442L;
private static final Unsafe unsafe = Unsafe.getUnsafe();
// 儲存AtomicLong中value的記憶體地址便於快速操作
private static final long valueOffset;
// 獲取value的記憶體地址的邏輯操作
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicReference.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
private volatile V value;
// 以傳入的initialValue初始化value物件
public AtomicReference(V initialValue) {
value = initialValue;
}
// 以傳入的null初始化value物件
public AtomicReference() {
}
}
AtomicReference的get操作
AtomicReference的get操作相比之前的AtomicLong的get操作少了getAndIncrement()等自增自減的操作,只支援整個物件的更新。
- getAndSet()方法取出原來的值並更新新值newValue
- getAndUpdate()、getAndAccumulate()等操作通過compareAndSet()操作完成原子性的物件更新
public final V get() {
return value;
}
@SuppressWarnings("unchecked")
public final V getAndSet(V newValue) {
return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
}
public final V getAndUpdate(UnaryOperator<V> updateFunction) {
V prev, next;
do {
prev = get();
next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return prev;
}
public final V getAndAccumulate(V x,
BinaryOperator<V> accumulatorFunction) {
V prev, next;
do {
prev = get();
next = accumulatorFunction.apply(prev, x);
} while (!compareAndSet(prev, next));
return prev;
}
AtomicReference的set操作
AtomicReference的set操作是通過unsafe.compareAndSwapObject()方法實現原子性操作,updateAndGet()方法只有在原子性更新成功後才能返回更新後的物件。
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 updateAndGet(UnaryOperator<V> updateFunction) {
V prev, next;
do {
prev = get();
next = updateFunction.apply(prev);
} while (!compareAndSet(prev, next));
return next;
}
public final V accumulateAndGet(V x,
BinaryOperator<V> accumulatorFunction) {
V prev, next;
do {
prev = get();
next = accumulatorFunction.apply(prev, x);
} while (!compareAndSet(prev, next));
return next;
}
案例
// 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
文末彩蛋
對高手而言
自律是一種生活方式
若只是間歇性的熱血沸騰
不可能成功
很多工作拼的不是才華
而是持續和穩定
所以先把你的勤奮變成現在進行時吧!
剔除自我感動,也學會自我成全
工作、程式碼、寫作、跑步,近乎苦行僧般的生活讓我感到很踏實
相關文章
- java原始碼-CountDownLatchJava原始碼CountDownLatch
- java原始碼-SemaphoreJava原始碼
- Java集合原始碼剖析——ArrayList原始碼剖析Java原始碼
- 【Java集合原始碼剖析】ArrayList原始碼剖析Java原始碼
- 【Java集合原始碼剖析】Vector原始碼剖析Java原始碼
- 【Java集合原始碼剖析】HashMap原始碼剖析Java原始碼HashMap
- 【Java集合原始碼剖析】Hashtable原始碼剖析Java原始碼
- 【Java集合原始碼剖析】TreeMap原始碼剖析Java原始碼
- Java容器原始碼學習--ArrayList原始碼分析Java原始碼
- 【Java集合原始碼剖析】LinkedList原始碼剖析Java原始碼
- 【Java集合原始碼剖析】LinkedHashmap原始碼剖析Java原始碼HashMap
- java原始碼-java.util.ListJava原始碼
- java 原始碼分析 —BooleanJava原始碼Boolean
- java原始碼-AtomicIntegerJava原始碼
- java原始碼-BufferedReaderJava原始碼
- Java——HashMap原始碼解析JavaHashMap原始碼
- Java——ArrayList原始碼解析Java原始碼
- Java 原始碼如何分析?Java原始碼
- Java原始碼系列 -- HashSetJava原始碼
- 搞懂 Java ArrayList 原始碼Java原始碼
- Java:HashMap原始碼分析JavaHashMap原始碼
- 搞懂 Java HashMap 原始碼JavaHashMap原始碼
- Java Collections 原始碼分析Java原始碼
- Java WeakHashMap 原始碼解析JavaHashMap原始碼
- Java TreeMap 原始碼解析Java原始碼
- Java集合類原始碼Java原始碼
- Java 原始碼,反碼和補碼Java原始碼
- 【Java集合原始碼剖析】Java集合框架Java原始碼框架
- Java String原始碼分析Java原始碼
- 如何閱讀Java原始碼?Java原始碼
- 【Java】ServiceLoader原始碼分析Java原始碼
- 【Java原始碼】集合類-ArrayDequeJava原始碼
- Java LinkedList 原始碼剖析Java原始碼
- 【Java集合】ArrayList原始碼分析Java原始碼
- java原始碼-ThreadPoolExecutor(2)Java原始碼thread
- Java集合原始碼探究~ListJava原始碼
- java原始碼學習-SpliteratorJava原始碼
- Java——LinkedHashMap原始碼解析JavaHashMap原始碼