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基本一样,这里只是简单贴一下:

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;

好了,接着说几个方法。

/**设定给的值*/
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);
} 

上面一组方法是将当前值修改为给定的值,下面再来看另一组按一定增量来增(减)当前的值。

/**
*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新增的几个方法

/**
*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的两个示例:

@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方法。

你可能感兴趣的:(java,源码学习)