JAVA並發API源碼解析:原子類,api源碼
在JAVA API的java.util.concurrent.atomic包下提供了一系列以基本類型封裝類為基礎的並發情況下不需要同步的類(藉助硬體相關指令實現)。
首先看一個例子AutomicInteger:
public class AtomicInteger extends Number implements java.io.Serializable { private static final long serialVersionUID = 6214790243416807050L; private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } private volatile int value; public AtomicInteger(int initialValue) { value = initialValue; } public AtomicInteger() { } public final int get() { return value; } public final void set(int newValue) { value = newValue; } public final void lazySet(int newValue) { unsafe.putOrderedInt(this, valueOffset, newValue); } public final int getAndSet(int newValue) { for (;;) { int current = get(); if (compareAndSet(current, newValue)) return current; } } public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } public final boolean weakCompareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } public final int getAndIncrement() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return current; } } public final int getAndDecrement() { for (;;) { int current = get(); int next = current - 1; if (compareAndSet(current, next)) return current; } } public final int getAndAdd(int delta) { for (;;) { int current = get(); int next = current + delta; if (compareAndSet(current, next)) return current; } } public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } } public final int decrementAndGet() { for (;;) { int current = get(); int next = current - 1; if (compareAndSet(current, next)) return next; } } public final int addAndGet(int delta) { for (;;) { int current = get(); int next = current + delta; if (compareAndSet(current, next)) return next; } } public String toString() { return Integer.toString(get()); } public int intValue() { return get(); } public long longValue() { return (long)get(); } public float floatValue() { return (float)get(); } public double doubleValue() { return (double)get(); }}
原始碼中沒有volatile或者synchronized這些同步機制也沒有鎖,其實它的同步是通過硬體指令實現。Integer內部方法不是安全執行緒的所以並發編程推薦使用AtomicInteger類來替換封裝類,但是原子類不是 java.lang.Integer 和相關類的通用替換方法,它們不定義諸如 hashCode 和 compareTo 之類的方法。例如:不提供AtomicDouble,開發人員需要使用 Double.doubleToLongBits 和 Double.longBitsToDouble 轉換來保持 double 值。
此包還包含 Updater 類,該類可用於擷取任意選定類的任意選定 volatile 欄位上的 compareAndSet 操作。解決volatile欄位非原子操作的安全問題。