1/21/2014
3:25:00 PM 0

Java Atomic Operation

定義
代表一種不可再分割的操作,在 multithreading 的環境中 Atomic Operation 是達成 thread-safe 的方法之一
至於為什麼會取名 Atomic 呢? 可能是過去原子被認定為物質的最小單位,無法再分割有關

舉例來說,當我們在 Java 中執行宣告 int i = 12 會配置 32 bits 的記憶體空間並將 12 這個值寫到記憶體區塊中,將整數 12 寫入記憶體這個操作是一個 Atomic Operation,不會只做一半就被其他操作中斷,而影響指派(assignment)值的正確性

使用硬體裝置支援的 Atomic Operation 可有效地提高程式效率, Intel Software Developer’s Manual 有說明哪些操作 Guaranteed Atomic Operations

Java 除了 double 和 long 這兩個資料型別以外,所有的 primitive types & reference types 讀取和寫入操作都是 Atomic Operation, 宣告為 volatile 的 double 和 long 讀取和寫入操作也視為 Atomic Operation

從 Java 1.5 開始,增加了package java.util.concurrent.atomic,可以在不使用 lock 的狀況下,達到 thread-safe 的目的

舉個例子
我們如果要寫個 thread-safe 的計數器,Java 1.4 的作法
public class Counter {
    private int count = 0;

    public synchronized int incrementCount() {
        return ++count;
    }
}
在 Java 中 ++count 這個操作,不是 atomic operation 因此是 non-thread-safe,做個細部分解,++count至少包含三個以上的動作
  1. 讀取count的值
  2. 將步驟1讀取出的值加1
  3. 將步驟2計算完成的值寫回變數count
從 x86 CPU 的角度來看,會使用三條指令來處理
  1. 從 memory 讀取 count 值到 register
  2. 對 register 的值加 1
  3. 把新值寫回 count 所在的 memory address
在多執行緒的環境下為了 thread-safe,所以必須使用 synchronized 關鍵字,synchronized 可達到 mutex & visibility 的目的

Java 1.5 後就可以使用 AtomicInteger 來替代 lock,相當於使用了 CPU 的 compare and swap 指令,在 x86 的架構中稱作 compare and exchange,使用 AtomicInteger 的另一項優點是 visibility,所以記憶體的值是一致的(memory consistency)
public class Counter {
    private final AtomicInteger count = new AtomicInteger(0);

    public int incrementCount() {
        return count.incrementAndGet();
    }
}
所有 java.util.concurrent.atomic package classes 都使用 Atomic 開頭, 包含以下 classes
  • AtomicBoolean
  • AtomicInteger
  • AtomicIntegerArray
  • AtomicIntegerFieldUpdater
  • AtomicLong
  • AtomicLongArray
  • AtomicLongFieldUpdater
  • AtomicMarkableReference
  • AtomicReference
  • AtomicReferenceArray
  • AtomicReferenceFieldUpdater
  • AtomicStampedReference

0 comments:

Post a Comment