原子變量與CAS算法小結

CAS算法

  • CAS(compare-and-swap)是一種硬件對併發的支持,針對多處理器操作而設計的處理器中的一種特殊指令,用於管理對共享數據的併發訪問。

  • CAS是一種無鎖非阻塞算法的實現。

  • CAS 包含了 3 個操作數:
    需要讀寫的內存值V
    進行比較的值A
    擬寫入的新值B

  • 當且僅當V的值等於A時,CAS通過原子方式用新值更新V的值,否則不會執行任何操作。

CAS操作過程如下所示

CAS操作過程

CAS算法模擬

/**
 * 模擬CAS算法
 *
 * Created by 吳海飛 on 2017-1-22.
 */
public class TestCompareAndSwap {
    public static void main(String[] args){
        final CompareAndSwap cas = new CompareAndSwap();

        for (int i = 0; i < 10; i++ ){
            new Thread(new Runnable() {
                        @Override
                        public void run() {
                            int expectValue = cas.getValue();
                            boolean b = cas.compareAndSet(expectValue, (int)(Math.random() * 101));
                            System.out.println(b);
                        }
                    }
            ).start();
        }

    }
}

class CompareAndSwap{
    private int value;

    //獲取內存值
    public synchronized int getValue(){
        return this.value;
    }
    //比較
    public synchronized int compareAndSwap(int expectValue,int newValue){
        int oldValue = this.value;
        if(oldValue == expectValue){//如果期望值等於舊值
            this.value = newValue;
        }
        return oldValue;
    }

    public synchronized boolean compareAndSet(int expectValue,int newValue){
        return expectValue == compareAndSwap(expectValue, newValue);
    }

}

原子變量

  • 類的小工具包,支持在單個變量上解除鎖的線程安全編程。事實上,此包中的類可將 volatile 值、字段和數組元素的概念擴展到那些也提供原子條件更新操作的類。

  • 類 AtomicBoolean、 AtomicInteger、 AtomicLong 和 AtomicReference 的實例各自提供對相應類型單個變量的訪問和更新。每個類也爲該類型提供適當的實用工具方法。

  • AtomicIntegerArray、 AtomicLongArray 和 AtomicReferenceArray 類進一步擴展了原子操作,對這些類型的數組提供了支持。這些類在爲其數組元素提供 volatile 訪問語義方面也引人注目,這對於普通數組來說是不受支持的。

  • 核心方法: boolean compareAndSet(expectedValue, updateValue)

    • java.util.concurrent.atomic 包下提供了一些原子操作的常用類:

      1. AtomicBoolean 、 AtomicInteger 、 AtomicLong 、AtomicReference
      2. AtomicIntegerArray 、 AtomicLongArray
      3. AtomicMarkableReference
      4. AtomicReferenceArray
      5. AtomicStampedReference

    原子變量使用Demo

import java.util.concurrent.atomic.AtomicInteger;

/**
 *一、i++ 的原子性問題:i++ 的操作實際上分爲三個步驟“讀-改-寫”
 *        int i = 10;
 *        i = i++; //10
 *
 *        int temp = i;
 *        i = i + 1;
 *        i = temp;
 * 二、原子變量:在 java.util.concurrent.atomic 包下提供了一些原子變量。
 *      1. volatile 保證內存可見性
 *      2. CAS(Compare-And-Swap) 算法保證數據變量的原子性
 *          CAS 算法是硬件對於併發操作的支持
 *          CAS 包含了三個操作數:
 *          ①內存值  V
 *          ②預估值  A
 *          ③更新值  B
 *          當且僅當 V == A 時, V = B; 否則,不會執行任何操作。
 */

public class AtomicDemo {
    public static void main(String[] args) {
        AtomicData ad = new AtomicData();
        for (int i = 0; i < 10; i++) {
            new Thread(ad).start();
        }
    }
}

class AtomicData implements Runnable{
    //初始化原子變量
    private AtomicInteger atomicData = new AtomicInteger(0);

    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(getAtomicData());
    }

    public int getAtomicData(){
        return atomicData.getAndIncrement();//相當於atomicData++
    }

}
發佈了46 篇原創文章 · 獲贊 14 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章