首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java JUC 原子類:AtomicLong 原子長整型操作詳解與 CAS 原理

     編輯:Java 相關知識

1. AtomicLong 簡介

提供對 long 類型的原子操作。32 位 JVM 下 long/double 非原子(拆兩次 32 位操作),AtomicLong 保證原子性。

2. 核心方法

  • 構造:AtomicLong()、AtomicLong(long initialValue)
  • 基本:get()、set(v)、lazySet(v)
  • 增減:getAndIncrement()、incrementAndGet()、getAndDecrement()、decrementAndGet()
  • 加法:getAndAdd(delta)、addAndGet(delta)
  • CAS:compareAndSet(expect, update)、weakCompareAndSet(expect, update)
  • 其他:getAndSet(v)、類型轉換方法(intValue() 等)。

3. 源碼核心:以 incrementAndGet 為例(JDK 1.7.0_40)

public class AtomicLong extends Number implements Serializable {
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;
    private volatile long value; // volatile 保證可見性

    public final long incrementAndGet() {
        for (;;) {
            long current = get();          // 讀取最新值
            long next = current + 1;       // 計算新值
            if (compareAndSet(current, next)) return next; // CAS 更新
        }
    }
    public final boolean compareAndSet(long expect, long update) {
        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
    }
}

原理:volatile 保證線程間可見性;Unsafe.compareAndSwapLong 硬件級 CAS 指令保證「讀-改-寫」原子性,無需鎖。

4. 完整示例與輸出

// LongTest.java
AtomicLong m = new AtomicLong();
m.set(0x0123456789ABCDEFL);
System.out.printf("get(): 0x%016X\n", m.get());
System.out.printf("getAndDecrement(): 0x%016X\n", m.getAndDecrement());
System.out.printf("decrementAndGet(): 0x%016X\n", m.decrementAndGet());
System.out.printf("getAndIncrement(): 0x%016X\n", m.getAndIncrement());
System.out.printf("incrementAndGet(): 0x%016X\n", m.incrementAndGet());
System.out.printf("addAndGet(0x10): 0x%016X\n", m.addAndGet(0x10));
System.out.printf("getAndAdd(0x10): 0x%016X\n", m.getAndAdd(0x10));
System.out.printf("compareAndSet(0x12345679L, 0xFEDCBA9876543210L): %s\n", m.compareAndSet(0x12345679L, 0xFEDCBA9876543210L));

運行結果節選

get(): 0x0123456789ABCDEF
getAndDecrement(): 0x0123456789ABCDEF
decrementAndGet(): 0x0123456789ABCDED
getAndIncrement(): 0x0123456789ABCDED
incrementAndGet(): 0x0123456789ABCDEF
addAndGet(0x10): 0x0123456789ABCDFF
compareAndSet(...): false  // 期望值不匹配,更新失敗
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved