并发包 源码分析 AtomicInteger

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

private static final Unsafe unsafe = Unsafe.getUnsafe();unsafe类是涉及到底层的C语言编写的程序集
private static final long valueOffset;设置一个偏移量

static {
  try {
            valueOffset = unsafe.objectFieldOffset

          (AtomicInteger.class.getDeclaredField("value"));
   } catch (Exception ex) { throw new Error(ex); }
}

可以看到这是用反射的方式初始化这个偏移量
  private volatile int value;

这个就是承接int数据的value。

例如我们在执行i++的时候,这个value就是承接i的值的。

请注意这个变量是volatile类型的,说明他是内存可见的。也就是一个线程对其修改,另一个线程立马可见。

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

有参构造器

 

    public AtomicInteger() {
    }
无参构造器

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

只是一个简单的getset方法,没有任何的并发安全控制。
    public final void lazySet(int newValue) {
        unsafe.putOrderedInt(this, valueOffset, newValue);
    }
set()会立刻修改旧值,别的线程可以立刻看到更新后的值;而lazySet不会立刻(但是最终会)修改旧值,别的线程看到新值的时间会延迟一些。
    public final int getAndSet(int newValue) {
        return unsafe.getAndSetInt(this, valueOffset, newValue);
    }
以原子方式设置为给定值,并返回以前的值。
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

这就是整个AtomXXX的核心,CAS

CAS就是CompareAndSwap,即比较并交换

这是一个底层的方法

主要实现的功能就是左手拿着一个当前应该存在的int值,右手拿着一个自己更新后的int值,跑到内存中,先拿左手的当前值跟内存里的值进行比较,如果一样则用新值覆盖旧值返回True,否则返回False。

    public final boolean weakCompareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
在正常情况下weak版本比compareAndSet更高效,但是不同的是任何给定的weakCompareAndSet方法的调用都可能会返回一个虚假的失败( 无任何明显的原因 )。一个失败的返回意味着,操作将会重新执行如果需要的话,重复操作依赖的保证是当变量持有expectedValue的值并且没有其他的线程也尝试设置这个值将最终操作成功。

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

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

调用unsafe方法 getAndAddInt();

 

getAndIncrement就是返回当前值,并且对当前值+1。

getAndDecrement就是返回当前值,并且对当前值-1.

 

 

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

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

这两个方法相似,都是先获取当前值然后进行+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;
    }

可以看出相比上述方法,这个方法多了一个int delta 参数,其实就是不仅仅是增加一减小一的事儿了 你可以自己设值。

 

两个方法有区别 就是一个是先get 另一个是先add。方法体也有不同,add优先的方法最后还要多出一部 + delta。

 

实际上第一个方法返回的是更新前的值,后一个方法返回的是更新后的值。

    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 (!compareAndSet(prev, next));
        return next;
    }

首先看名称一个是getAndUpdate,另一个updateAndGet。

那么这就说明了

第一个是获取更新前的值

第二个是获取更新后的值

 

那么剩下的就是这个IntUnaryOperator ,他是什么???

这其实就是个Java的函数式编程接口,具体如何使用自行查阅资料。不是本文重点。

    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 (!compareAndSet(prev, next));
        return next;
    }

注意看名字,这里又是类似的命名方式,先get还是后get的事儿,主要看参数:

int x;
IntBinaryOperator accumulatorFunction;

 

其实说白了就是

给定一个数,做一些函数操作,然后返回。

之后的事情就是CAS所做的是,对比获取到的值和实际值,相同交换返回true不相同就返回false

}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值