源码:并发包-AtomicInteger的源码解析

花了一点时间看了一下源码,记录了一下,在这里把记录的东西贴出来,和前边的文章有一些区别

 public class AtomicInteger extends Number implements java.io.Serializable {
    private static final long serialVersionUID = 6214790243416807050L;

    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

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

    private volatile int value;

    /**
     * 有值的构造对象
     */
    public AtomicInteger(int initialValue) {
      value = initialValue;
    }

    /**
     * 无值的构造函数
     */
    public AtomicInteger() {
    }

    /**
     * 获取值
     */
    public final int get() {
      return value;
    }

    /**
     * 设置值
     */
    public final void set(int newValue) {
      value = newValue;
    }

    /**
     * 这块在上一篇文章中已经介绍过
     */
    public final void lazySet(int newValue) {
      unsafe.putOrderedInt(this, valueOffset, newValue);
    }

    /**
     * 获取并设置新值
     */
    public final int getAndSet(int newValue) {
      return unsafe.getAndSetInt(this, valueOffset, newValue);
    }

    /**
     * var1是对象,var2是偏移量,var4是新值
     */
    public final int getAndSetInt(Object var1, long var2, int var4) {
      int var5;
      do {
        /**
         * 通过对象和偏移量读取不经过缓存的值
         * https://stackoverflow.com/questions/48615456/what-is-difference-between-getxxxvolatile-vs-getxxx-in-java-unsafe
         */
        var5 = this.getIntVolatile(var1, var2);
        /**
         * 不成功会一直重试,并把原来的值返回
         */
      } while(!this.compareAndSwapInt(var1, var2, var5, var4));

      return var5;
    }

    /**
     * 比对set
     */
    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);
    }

    /**
     * 加1,返回的是旧的值
     */
    public final int getAndIncrement() {
      return unsafe.getAndAddInt(this, valueOffset, 1);
    }

    /**
     * 减1,返回的是旧的值
     */
    public final int getAndDecrement() {
      return unsafe.getAndAddInt(this, valueOffset, -1);
    }

    /**
     * 加1,返回的是新值
     */
    public final int incrementAndGet() {
      return unsafe.getAndAddInt(this, valueOffset, 1) + 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 getAndAddInt(Object var1, long var2, int var4) {
      int var5;
      do {
        var5 = this.getIntVolatile(var1, var2);
      } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

      return var5;
    }

    /**
     * addAndGet方法,addAndGet方法内部使用一个死循环,先得到当前的值value,然后再把当前的值加一,加完之后使用cas原子操作让当前值加一处理正确。
     * 当然cas原子操作不一定是成功的,所以做了一个死循环,当cas操作成功的时候返回数据。这里由于使用了cas原子操作,所以不会出现多线程处理错误的问题。
     * 比如线程A得到current为1,线程B也得到current为1;线程A的next值为2,进行cas操作并且成功的时候,将value修改成了2;这个时候线程B也得到next值为2,
     * 当进行cas操作的时候由于expected值已经是2,而不是1了;所以cas操作会失败,下一次循环的时候得到的current就变成了2;也就不会出现多线程处理问题了
     */
    public final int addAndGet(int delta) {
      return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
    }


    /**
     *这个方法是 Java 1.8 开始提供的,这个方法自身返回当前值。
     * 同时会把 updateFunction 的返回值设置为新值
     */
    public final int getAndUpdate(IntUnaryOperator updateFunction) {
      int prev, next;
      do {
        prev = get();
        next = updateFunction.applyAsInt(prev);
      } while (!compareAndSet(prev, next));
      return prev;
    }

    /**
     * 用法多线程环境下安全更新Integer i = ai.updateAndGet(x -> 5);
     */
    public final int updateAndGet(IntUnaryOperator updateFunction) {
      int prev, next;
      do {
        prev = get();
        next = updateFunction.applyAsInt(prev);
      } while (!compareAndSet(prev, next));
      return next;
    }

    /**
     * 1.8加入,多线程环境下安全更新  将原子值和传入的参数组合
     * !compareAndSet(prev, next)这是一个竞态的条件,满足的时候才会更新
     * compareAndSet相当于是原语的,原子操作
     * 返回的是旧值
     */
    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;
    }

    /**
     * 1.8加入,多线程环境下安全更新  将原子值和传入的参数组合
     * !compareAndSet(prev, next)这是一个竞态的条件,满足的时候才会更新
     * compareAndSet相当于是原语的,原子操作
     * 返回的是新值
     */
    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;
    }

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

    /**
     * 获取值
     */
    public int intValue() {
      return get();
    }

    /**
     * 强转long
     */
    public long longValue() {
      return (long)get();
    }

    /**
     * 强转float
     */
    public float floatValue() {
      return (float)get();
    }

    /**
     * 强转double
     */
    public double doubleValue() {
      return (double)get();
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值