CAS原理

synchronized這種獨佔鎖屬於悲觀鎖,它是在假設必定會發生衝突的,那麼加鎖剛好有用,除此以外,還有樂觀鎖,樂觀鎖的含義就是假設沒有發生衝突,那麼我正好能夠進行某項操做,若是要是發生衝突呢,那我就重試直到成功,樂觀鎖最多見的就是CAS編程

咱們在讀Concurrent包下的類的源碼時,發現不管是ReenterLock內部的AQS,仍是各類Atomic開頭的原子類,內部都應用到了CAS,最多見的就是咱們在併發編程時遇到的i++這種狀況。傳統的方法確定是在方法上加上synchronized關鍵字:bash

public class Test {

    public volatile int i;

    public synchronized void add() {
        i++;
    }
}
複製代碼

可是這種方法在性能上可能會差一點,咱們還可使用AtomicInteger,就能夠保證i原子的++了。併發

public class Test {

    public AtomicInteger i;

    public void add() {
        i.getAndIncrement();
    }
}複製代碼

CAS源碼分析源碼分析

獲取偏移量valueOffset,性能

public native long objectFieldOffset(Field var1);經過這個方法能夠知道偏移量從jdk底層源碼中獲取。ui

static {
    try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
}複製代碼

而後再看看增長的方法this

public final int getAndAdd(int delta) {
    return unsafe.getAndAddInt(this, valueOffset, delta);
}複製代碼
public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

    return var5;
}複製代碼
咱們看 var5獲取的是什麼,經過調用 unsafe的getIntVolatile(var1, var2),這是個native方法,具體實現到JDK源碼裏去看了,其實就是獲取 var1中, var2偏移量處的值。 var1就是 AtomicIntegervar2就是咱們前面提到的valueOffset,這樣咱們就從內存裏獲取到如今valueOffset處的值了

compareAndSwapInt(var1, var2, var5, var5 + var4)換成compareAndSwapInt(obj, offset, expect, update)比較清楚,意思就是若是obj內的valueexpect相等,就證實沒有其餘線程改變過這個變量,那麼就更新它爲update,若是這一步的CAS沒有成功,那就採用自旋的方式繼續進行CAS操做spa

private volatile int value;和unsafe.getAndAddInt(this, valueOffset, delta);
能夠看出compareAndSwapInt(obj, offset, expect, update)中的obj爲AtomicInteger類型,
AtomicInteger的value值爲volatile類型,在看
 do {
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));這裏是一個dowhile循環,若是obj內的value和expect不相等,
var5 = this.getIntVolatile(var1, var2);一直會
執行,即不斷從內存中獲取最新的值,來與obj內的value進行比較直到相等爲止。從這個字段能夠看出複製代碼

CAS的缺點線程

  1. 只能保證對一個變量的原子性操做
  2. 長時間自旋會給CPU帶來壓力
  3. ABA問題
相關文章
相關標籤/搜索