2026/05/04

Java Atomic Variables

java.util.concurrent.atomic 定義了對單一變數進行 atomic operations 的類別,所有類別都有 get 與 set methods,可讀寫 volatile variables。set 可確定會在 get 的前面先處理。

對於物件管理,如果有兩個 thread 同時做 get/set,會導致資料異常,所以通常會在 set method 加上 synchronized 來限制一次只有一個 thread 進入該 method

例如

Counter 類別的變數 c,會因為多個 thread 同時使用而異常

class Counter {
    private int c = 0;

    public void increment() {
        c++;
    }

    public void decrement() {
        c--;
    }

    public int value() {
        return c;
    }

}

所以會改寫為

class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }

}

synchronized 可解決 multi-thread 問題,但會產生效能問題。

以 AtomicInteger 改寫

import java.util.concurrent.atomic.AtomicInteger;

class AtomicCounter {
    private AtomicInteger c = new AtomicInteger(0);

    public void increment() {
        c.incrementAndGet();
    }

    public void decrement() {
        c.decrementAndGet();
    }

    public int value() {
        return c.get();
    }

}

Atomic Operation

non-blocking 演算法提供了 compare-and-swap CAS 方法,可確保資料完整性。

CAS operation 使用以下三個 operands

  1. M 要操作 operate 的記憶體位置

  2. A 該變數期待的既有原始數值

  3. B 需要被設定的新數值

CAS operation 可自動 atomically 從 M 到 B 更新數值,只會在 M 確認為 A 時,更新為 B

因此可不使用 synchronization lock,完成資料的更新,沒有 thread 會被 suspended,也不需要 context switching。


常用的 Atomic Variables 有 AtomicInteger, AtomicLong, AtomicBoolean, AtomicReference,分別代表 int, long, boolean, object reference 這些數值可自動被安全地更新,主要 methods 有

  • get()

    等同於讀取 volatile variable,可直接取得其他 thread 更新的數值

  • incrementAndGet()

  • set()

    等同於寫入 volatile variable

  • lazySet()

    最終會寫入變數,但不保證可立即被其他 thread 取得。速度比 set 更快。可用在 cache,或被 gc 的資料

  • compareAndSet()

    成功就回傳 true

  • weakCompareAndSetPlain(), weakCompareAndSetVolatile()

    weakCompareAndSet() 已被 deprecated

References

# Atomic Variables Java Tutorial

An Introduction to Atomic Variables in Java | Baeldung

java.util.concurrent.atomic (Java SE 25 & JDK 25)

Atomic Variables in Java with Examples - GeeksforGeeks