Java 5 引入的 java.util.concurrent.atomic 套件,提供了一系列原子操作類,能夠在多執行緒環境下對基本資料類型、陣列元素以及物件欄位進行無鎖的線程安全操作。這些類別基於 CAS(Compare-And-Swap)硬體指令實現,效能遠優於傳統的 synchronized 鎖機制。
以下範例展示如何使用 AtomicInteger 實現線程安全的售票系統:
public class AtomicTest {
public static void main(String[] args) {
final Ticket ticket = new Ticket();
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {
@Override
public void run() {
while (ticket.getCount() > 0) {
System.out.println(Thread.currentThread().getName() + " count: " + ticket.decrement());
}
}
}).start();
}
}
}
class Ticket {
public AtomicInteger count = new AtomicInteger(100);
public int decrement() {
return count.getAndDecrement();
}
public int getCount() {
return count.get();
}
}
AtomicIntegerArray 針對整數陣列中的元素提供原子操作,適用於需要對陣列特定索引進行並發修改的場景:
AtomicIntegerArray array = new AtomicIntegerArray(new int[]{1, 2, 3, 4, 5});
// 原子性地將索引 2 的元素加 10
array.getAndAdd(2, 10);
AtomicIntegerFieldUpdater 通過反射機制,對指定物件的 volatile int 欄位進行原子更新,適用於無法修改類定義(如第三方庫)的情況:
public class User {
public volatile int score; // 必須是 volatile
}
AtomicIntegerFieldUpdater<User> updater =
AtomicIntegerFieldUpdater.newUpdater(User.class, "score");
User user = new User();
updater.incrementAndGet(user); // 原子性遞增
原子類別適用於計數器、序號生成器、狀態標誌等高併發讀寫場景。相比 synchronized,它們避免了線程阻塞和上下文切換開銷,在低競爭情況下效能提升顯著。但需注意:複合操作(如先檢查再更新)仍需額外同步機制保證原子性。