切換語言為:簡體

Java 中 CAS 的原理及執行過程

  • 爱糖宝
  • 2024-07-31
  • 2064
  • 0
  • 0

CAS(Compare and Swap)是一種輕量級的同步操作,也是樂觀鎖的一種實現,它用於實現多執行緒環境下的併發演算法。CAS 操作包含三個運算元:記憶體位置(或者說是一個變數的引用)、預期的值和新值。如果記憶體位置的值和預期值相等,那麼處理器會自動將該位置的值更新為新值,否則不進行任何操作。

在多執行緒環境中,CAS 可以實現非阻塞演算法,避免了使用鎖所帶來的上下文切換、排程延遲、死鎖等問題,因此被廣泛應用於併發程式設計中。

# CAS 示例

在 Java 中,CAS 操作被封裝在 Atomic 類中,例如 AtomicInteger 類就是利用了 CAS 操作來實現執行緒安全的自增操作。同時,Java 還提供了一些工具類來支援 CAS 操作,例如 Unsafe 類,它提供了一些原始的 CAS 操作方法,供 JVM 內部使用,比如以下是基於 Unsafe 類的 CAS 示例:

import sun.misc.Unsafe;import java.lang.reflect.Field;import java.util.concurrent.TimeUnit;public class CASDemo {
    private volatile int value = 0;
    private static Unsafe unsafe;
    private static long valueOffset;

    static {
        try {
            // 透過反射獲取rt.jar包中的Unsafe類,預設Unsafe類是不能使用的
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
            valueOffset = unsafe.objectFieldOffset(CASDemo.class.getDeclaredField("value"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void addOne() {
        int current;
        do {
            current = unsafe.getIntVolatile(this, valueOffset);
        } while (!unsafe.compareAndSwapInt(this, valueOffset, current, current + 1));
    }

    public static void main(String[] args) throws InterruptedException {
        final CASDemo casDemo = new CASDemo();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    casDemo.addOne();
                }
            }).start();
        }
        TimeUnit.SECONDS.sleep(5);
        System.out.println(casDemo.value);
    }
    }

以上程式的執行結果為:

10000

程式開啟了 10 個執行緒,每個執行緒呼叫 1000 次,最終執行的結果是 10000,說明以上程式是執行緒安全的。

# CAS 執行流程

CAS 執行的具體流程如下:

  1. 將需要修改的值從主記憶體中讀入本地執行緒快取(工作記憶體);

  2. 執行 CAS 操作,將本地執行緒快取中的值與主記憶體中的值進行比較;

  3. 如果本地執行緒快取中的值與主記憶體中的值相等,則將需要修改的值在本地執行緒快取中修改;

  4. 如果修改成功,將修改後的值寫入主記憶體,並返回修改結果;如果失敗,則返回當前主記憶體中的值;

  5. 在多執行緒併發執行的情況下,如果多個執行緒同時執行 CAS 操作,只有一個執行緒的 CAS 操作會成功,其他執行緒的 CAS 操作都會失敗,這也是 CAS 的原子性保證。


0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.