線程安全之原子操作 待續~

原子操作,可以是一個步驟,也可以是多個操作步驟,但是其順序不可以被打亂,也不可以被切割而只執行其中一部分(不可中斷性),將整個操作視爲一個整體,資源在該次操作中保持一致,這是原子性的核心特徵。

CAS機制

compare and swap,屬於硬件同步原語,處理器提供了基本內存操作的原子性保證。

CAS操作,需要輸入兩個數值,一箇舊值一個新值,在操作期間先比較下舊值有沒有發生變化,如果沒有發生變化,才交換成新值;如果發生了變化,則不交換。

使用Java中Unsafe類實現CAS機制:

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;

public class UnsafeTest {

    private volatile int index = 0;

    // 類似直接操作內存
    private static Unsafe unsafe;

    // 屬性內存偏移量
    private static long indexOffset;

    static {
        try {
            // 通過反射拿到對象
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            unsafe = (Unsafe) theUnsafe.get(null);
            // 通過屬性偏移量,定位內存中具體對象內具體屬性的內存地址
            indexOffset = unsafe.objectFieldOffset(UnsafeTest.class.getDeclaredField("index"));
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public void incr() {
        int currentIndex;
        int newIndex;
        do {
            currentIndex = unsafe.getIntVolatile(this, indexOffset);
            newIndex = currentIndex + 1;
        } while (!unsafe.compareAndSwapInt(this, indexOffset, currentIndex, newIndex));
        // CAS 如果index值發生變化,操作失敗,直到修改成功跳出循環
    }

    public int getIndex() {
        return index;
    }

    public static void main(String[] args) throws InterruptedException {
        UnsafeTest unsafeTest = new UnsafeTest();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 10000; j++) {
                    unsafeTest.incr();
                }
            }).start();
        }
        TimeUnit.SECONDS.sleep(2);
        System.out.println(unsafeTest.getIndex());
    }

}

當然在JDK中已經給我們提供了很多原子操作封裝類,在java.util.concurrent.atomic這個包下,也就是平常說的JUC包下的atomic包;

原子類分四類

  1. 基本類型
    1. AtomicBoolean
    2. AtomicInteger
    3. AtomicLong
  2. 數組類型
    1. AtomicIntegerArray
    2. AtomicLongArray
    3. AtomicReferenceArray
  3. 引用類型
    1. AtomicReference
    2. AtomicStampedReference
    3. AtomicMarkableReference
  4. 對象屬性修改類型
    1. AtomicIntegerFieldUpdater
    2. AtomicLongFieldUpdater
    3. AtomicReferenceFieldUpdater

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章