AtomicInteger源碼學習

先看一下AtomicInteger類上的註釋:
'...An AtomicInteger is used in applications such as atomically incremented counters,and can not be replacement for an Integer.However,this class does extend Number to allow uniform access by tools and utilities that deal with numercally-based classes.'
AtomicInteger自身屬性及靜態代碼塊與AtomicBoolean基本同樣,這裏只是簡單貼一下:segmentfault

private static final Unsafe unsafe = Unsafe.getUnssafe();
private static final long offsetValue;
static {
    try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField('value'));
    }catch(Exception e){throw new Error(e);}
}
private volatile int value;

好了,接着說幾個方法。app

/**設定給的值*/
public final void set(int newValue){value = newValue;}
/**
*Eventually sets the given value
*這個方法是1.6加的
*/
public final void lazySet(int newValue){
    unsafe.putOrderInt(this,valueOffset,newValue);
}
/**
*Atomically sets to the given value and returns the old
* value.
*原子地修改給定的值,並返回舊值
*/
public final int getAndSet(int newValue){
    return unsafe.getAndSetInt(this,valueOffset,newValue);
}
/**
*Atomically sets the value to the given updated value
*if the current value == the expect value
*若是當前值(valueOffset偏移量對應的值)等於指望的值(expect),
*則原子地使用update修改當前值
*@return 若是修改爲功返回true,不然返回false
*/
public fianl boolean compareAndSet(int expect,int update){
    return unsafe.compareAndSwapInt(this,valueOffset,
                                        expect,update);
}

上面一組方法是將當前值修改成給定的值,下面再來看另外一組按必定增量來增(減)當前的值。this

/**
*Atomically increments by one the current value
*原子地將當前值加1
*返回舊值
*/
public fianl int getAndIncrement(){
    return unsafe.getAndAddInt(this,valueOffset,1);
}
/**
*功能同getAndIncrement相同,差別是這個方法返回新值
*/
public final int incrementAndGet(){
    return unsafe.getAndAddInt(this,valueOffset,1)+1;
}
/**
*原子將當前值減1
*返回舊值
*/
public final int getAndDecrement(){
    return unsafe.getAndAddInt(this,valueOffset,-1);
}
/**
*原子將當前值減1
*返回新值
*/
public final int decrementAndGet(){
    return unsafe.getAndAddInt(this,valueOffset,-1)-1;
}
/**
*將當前值新增給定的值
*返回舊值
*/
public final int getAndAdd(int delta){
    return unsafe.getAndAddInt(this,valueOffset delta);
}
/**
*將當前值新增給定的值
*返回新值
*/
public final int addAndGet(int delta){
    return unsafe.getAndAddInt(this,valueOffset delta)
                                        +delta;
}

再來看一組1.8新增的幾個方法atom

/**
*Atomically updates the current value with the resuls
* of applying the given function,returning thre previous
* value,...it may be  re-applied when attempted udates
* fail due to contention among threads.
*使用the given function的結果原子地更新當前,若是失敗會
*不停重試直到成功。
*返回舊值
*/
public final int getAndUpdate(IntUnaryOperator
                                updateFunction){
    int prev,next;
    do{
        prev = get();
        next = updateFunction.applyAsInt(prev);
    }while(!compareAndSet(prev,next));
    return prev;
}
與之類似的方法是updateAndGet,差異是這個方法返回新值。
/**
*...The function is applied with the current value as its
*first argument,and the given update as the second 
*argument.
*
*返回舊值
*/
public final int getAndAccumulate(int x,
                IntBinaryOperator accumulateFunction){
    int prev,next;
    do{
        prev = get();
        next = accumulateFunction.applyAsInt(prev,x);
    }while(!compareAndSet(prev,next));
    return prev;
}
一樣與之想似的方法accumulateAndGet,差異是這個方法返回新值

針對getAndUpdate與getAndAccumulate的兩個示例:code

@Test
public void testGetAndUpdate(){
    AtomicInteger atomicInteger = new AtomicInteger(1);
    //x爲當前值1,須要將當前值修改成x+3
    IntUnaryOperator function = x -> x + 3;
    int prev = atomicInteger.getAndUpdate(function);
    System.out.println("prev:"+prev+",next:"+
    atomicInteger.get());
    //結果輸出爲prev:1,next:4
}

@Test
public void testAccumulateAndGet(){
    AtomicInteger atomicInteger = new AtomicInteger(1);
    int updateValue = 2;
    //x爲當前值1,y是updateValue也就是2,須要將當前值修改成x+y
    IntBinaryOperator function = (x,y)->x+y;
    int prev = atomicInteger.accumulateAndGet(updateValue,
                                    function);
    System.out.println("prev:"+prev+",next:"+
                            atomicInteger.get());
    //結果輸出爲prev:1,next:3
}

這裏能夠看出來,getAndUpdate與accumulateAndGet分別依賴一元接口
IntUnaryOperator與二元接口IntBinaryOperator的具體實現,而且都是返回修改前的值,而updateAndGet與getAndAccumulate則是返回修改後的值。
至於複寫Number裏的幾個方法沒啥好說的,都是用了get方法。orm

相關文章
相關標籤/搜索