AtomicBoolean源碼學習

從AtomicBoolean源碼上的註釋看,AtomicBoolean用於應用中須要原子地更新flags,不過它不可以代替Boolean的使用,不能代替主要是從性能上考慮的吧。
1、先來看一下AtomicBoolean裏的屬性html

private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;

unsafe與valueOffset都是類級別的屬性。unsafe是Unsafe對象的引用,後面方法裏的原子操做都依賴它;valueOffset是AtomicBoolean對象地址偏移量,是unsafe對象方法裏的不可或缺的參數之一。git

static{
    try{
        valueOffset = unsafe.objectFieldOffset(
            AtomicBoolean.class.getDeclaredField("value"));
    }catch(Exception e){
        throw new Error(ex);
    }
}
private volatile int value;//修改後對其它線程當即可見

上面靜態塊在獲取屬性 'value' 的內存地址偏移量,這個偏移量對於給定的field是惟一的,而且每次調用返回都是同樣。
2、接着說幾個重要的方法
兩個構造器:github

public AtomicBoolean(boolean initialValue){
    value = initialValue ? 1 : 0;
}
public AtomicBoolean(){}

一個有參,一個無參,無參時成員變量value值爲0,也就是false.
再來看下面一組方法:緩存

/**
 *Atomically sets the value to the given updated value if
 *the current value == the expected value.
 *此方法最終由底層硬件緩存鎖實現原子性,不可中斷。偏移量所在的值
 *與傳入的expect相等且修改爲update則返回true,若是比較不相等則
 *返回false。這個方法不會自旋。
*/
public final boolean compareAndSet(boolean expect,boolean update){
    int e = expect ? 1 : 0;
    int u = update ? 1 : 0;
    return unsafe.compareAndSwapInt(this,valueOffset,e,u);
}
/**
*Atomically sets to the given value and returns the *previous value.
*設置新的舊並返回舊值,不成功會一直重試,compareAndSet則不會
*/
public final boolean getAndSet(boolean newValue){
    boolean prev;
    do{
        prev = get();
    }while(!(compareAndSet(prev,newValue));
    return prev;
}

再來一組方法:數據結構

/**
*Unconditionally sets to the given value
*無條件設置給定的值
*在修改value值時,會在其先後分別加StoreStore/StoreLoad內存
*屏障
*/
public final void set(boolean newValue){
    value = newValue ? 1 : 0;
}
/**
*Eventually sets to the given value
*最終設置給定的值,從字面上理解能夠看出必定延遲,不過確實也是
*lazySet可讓一個線程在沒有其它線程volatile寫或者synchronized
*動做發生前,本地緩存的寫能夠沒必要立刻刷回主存,
*有多是幾納秒後被其它線程可見,但性能聽說要比set快3倍。
*使用lazySet修改value時只會在其前加StoreStore屏障,
*這正是*lazySet比set效率高的緣由,正是這個特性使得lazySet很適合
*於SPSC的數據結構的實現
*SPSC:單product單consumer
*/
public fianl void lazySet(boolean newValue){
    int v = newValue ? 1 : 0;
    unsafe.putOrderedInt(this,valueOffset,v);
}

參考文章:
高性能SPSC無鎖隊列設計之路
set與lazySet區別
lazySet & set
sun.misc.Unsafe類詳解性能

相關文章
相關標籤/搜索