AtomicInteger源码详解

14 篇文章 0 订阅
14 篇文章 0 订阅

AtomicInteger类主要是为整型数据提供原子操作。

类定义

public class AtomicInteger extends Number implements java.io.Serializable {}

首先,AtomicInteger和Integer一样都继承了Number类,其次,实现了序列化的接口。

属性

private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
private volatile int value;
  1. unsafe属性主要是用来封装提供原子性操作的方法,AtomicInteger实现原子操作主要是通过unsafe来实现。
  2. valueOffset属性主要是指,value属性在AtomicInteger对象内部的偏移量。
  3. value属性就是AtomicInteger内部真正的整数值,而且是被volatile关键字修饰,主要是为了保证在多线程的环境下,内存可见性。

静态属性的初始化

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

这里对valueOffset在静态块中进行初始化,也是通过unsafe中的方法来实现。

构造方法

public AtomicInteger(int initialValue){
    value = initialValue;
}

public AtomicInteger(){}

AtomicInteger提供了两个构造方法,带有初始值的构造函数和无参的默认构造函数。

get和set方法

public final int get(){
    return value;
}

public final void set(int newValue){
    value = newValue;
}

lazySet方法

public final void lazySet(int newValue){
    unsafe.putOrderedInt(this, valueOffset, newValue);
}

提供lazySet的主要原因是,JDK的开发者对于极致性能的追求,在AtomicInteger中,其属性value是被关键字volatile修饰的,当我们修改value的值时,value的值会被强制刷新到内存中,从而保证了value属性在赋值时,能够立即被其他线程看到,保证了可见性。而这一切都要归功于volatile关键字底层的内存屏障。内存屏障虽然足够轻量,但是毕竟还是会带来性能上的开销,比如,在单线程中对AtomicInteger的value进行修改时没必要保留内存屏障,而value又是被volatile关键字修饰的,面对这种矛盾,只能提供一种更新volatile修饰的变量时,不使用内存屏障的方法,这就是lazySet方法。

get和set方法

public final int get(){
    return value;
}

public final void set(int newValue){
    value = newValue;
}

get用于获取value属性的值,set方法用于设置value属性的值,由于value是被volatile修饰的,更新后其他线程是立马可见的。

toString

public String toString(){
    return Integer.toString(get());
}

类型转换方法

public int intValue(){
    return get();
}

public float floatValue(){
    return (float)get();
}

public double doubleValue(){
    return (double)get();
}

获取设置方法

public final int getAndSet(int newValue){
    return unsafe.getAndSetInt(this, valueOffset, newValue);
}

该方法会原子性地value的值设置为newValue,并且会把value原来的值返回。

比较交换方法

public final boolean compareAndSet(int expect, int update){
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

public final boolean weakCompareAndSet(int expect, int update){
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

上述两个方法,虽然名称不同,但是实现是一样的。上述方法原子性地更新AtomicInteger的值,其中expect代表当前的AtomicInteger的值,update则是需要设置的新值,该方法会返回一个布尔值,当expect和AtomicInteger的当前值不相等时,更新失败,返false;如果修改成功,返回true.

获取自增方法

public final int getAndIncrement(){
    return unsafe.getAndAddInt(this, valueOffset, 1);
}

public final int incrementAndGet(){
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

getAndIncrement方法返回当前的value值,然后对value进行自增运算,该操作方法能够确保对value的原子性增量操作。

incrementAndGet方法直接返回自增后的结果,该方法能够确保对value的原子性增量操作。

获取自减方法

public final int getAndDecrement(){
    unsafe.getAndAddInt(this, valueOffset, -1);
}

public final int decrementAndGet(){
    return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
}

getAndDecrement返回当前的value值,然后对value进行自减运算,该操作方法能够确保对value的原子性减量操作。

decrementAndGet直接返回自减后的结果,该操作方法能够确保对value的原子性减量操作。

获取增加方法

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;
}

getAndAdd方法原子性地更新AtomicInteger的value值,更新后的value值为value和delta之和,方法返回为value之前的值,该方法实际上是基于自旋+CAS算法实现的原子性操作。

addAndGet该方法与getAndAdd一样,也是原子性地更新AtomicInteger的value值,更新后的结果value为value和delta之和,但是该方法会立即返回更新后的value值。

获取更新方法

public final int getAndUpdate(IntUnaryOperator updateFunction){
    int prev, next;
    do {
        prev = get();
        next = updateFunction.applyAsInt(prev);
    }while(!compareAndSet(prev, next));
    return prev;
}

public final int updateAndGet(IntUnaryOperator updateFunction){
    int prev, next;
    do {
        prev = get();
        next = updateFunction.applyAsInt(prev);
    }while(!compareAndSwap(prev, next));
    return next;
}

IntUnaryOperator是一个函数式接口,有且仅有一个接口方法,接口方法的返回值即AtomicInteger被更新后的value的最新值,定义如下所示:

@FunctionalInterface
public interface IntUnaryOperator{
    int applyAsInt(int operand);
}

getAndUpdate方法原子性地更新AtomicInteger的值,返回值为value更新之前的值。

updateAndGet方法原子性地更新AtomicInteger的值,返回值为value更新之后的值。

获取累加方法

public final int getAndAccumulate(int x, IntBinaryOperator accumulatorFunction){
    int prev, next;
    do{
        prev = get();
        next = accumulatorFunction.applyAsInt(prev, x);
    }while(!compareAndSet(prev, next));
    return prev;
}

public final int accumulateAndGet(int x, IntBinaryOperator accumulatorFunction){
    int prev, next;
    do{
        prev = get();
        next = accumulatorFunction.applyAsInt(prev, x);
    }while(!compareAndSwap(prev, next));
    
    return next;
}

IntBinaryOperator为函数式接口,有且仅有一个接口方法(非静态,非default),接口方法的返回值即AtomicInteger被更新后的value的最新值。

getAndAccumulate方法原子性地更新AtomicInteger的值,方法入参为IntBinaryOperator接口和delta值x,返回值为value更新之前的值。

accumulateAndGet方法与getAndAccumulate类似,只不过会立即返回AtomicInteger的更新值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值