AtomicInteger的addAndGet(int delta)与getAndAdd(int delta)有什么区别?
结论:区别仅在于返回的结果,修改的值是相同的,但是返回的值不同。
看一下源码注释
1 /** 2 * Atomically adds the given value to the current value. 3 * 4 * @param delta the value to add 5 * @return the updated value 6 */ 7 public final int addAndGet(int delta) { 8 return unsafe.getAndAddInt(this, valueOffset, delta) + delta; 9 } 10 11 /** 12 * Atomically adds the given value to the current value. 13 * 14 * @param delta the value to add 15 * @return the previous value 16 */ 17 public final int getAndAdd(int delta) { 18 return unsafe.getAndAddInt(this, valueOffset, delta); 19 }
注意看下划线,一个是更新后的值,一个是更新前的值
源码:(sun.misc.Unsafe#getAndAddInt)
1 public final int getAndAddInt(Object object, long offset, int update) { 2 int expect; 3 do { 4 expect = this.getIntVolatile(this, offset); 5 } while (!this.compareAndSwapInt(this, offset, expect, expect + update)); 6 7 return expect; 8 }
传入的形参就不必解释了,对照上面的代码应该能看懂
第二行,期望值
第四行,取内存(堆)中的数据
第五行,首先肯定要执行cas,然后就是根据返回值决定是否要继续执行。
这里有必要解释cas的执行过程,如下
1 int compare_and_swap(int *mem_val, int expect, int update) 2 { 3 int old_val; 4 old_val = *mem_val; 5 if(old_val == expect) *mem_val = update; 6 return old_val; 7 }
主要就是第五行,如果内存中的值和传进来的期望值相同,那就把内存中的值赋值为要更新的值,然后返回内存值。
可能有人对参数坑位有疑惑,这个问题其实仔细思考就能猜到。
object + offset => 定位到内存中对象属性的值
这样,也就能和内存值关联上了
写个demo试试
1 import java.util.concurrent.atomic.AtomicInteger; 2 3 /** 4 * @author Alin 5 * @date 2020/7/26 6 */ 7 public class TestAtomicInt { 8 static AtomicInteger count = new AtomicInteger(0); 9 10 public static void main(String[] args) { 11 //返回新值 12 System.out.println(count.addAndGet(20)); 13 System.out.println("\tcur = " + count.get()); 14 /** 15 * public final int getAndAddInt(Object this, long offset, int update) { 16 * int expect; 17 * do { 18 * expect = this.getIntVolatile(this, offset); 19 * } while(!this.compareAndSwapInt(this, offset, expect, expect + update)); 20 * 21 * return expect;//返回旧值 22 * } 23 */ 24 System.out.println(count.getAndAdd(2)); 25 //返回当前值 26 System.out.println("\tcur = " + count.get()); 27 28 } 29 }
结果
20
cur = 20
20
cur = 22
三分热血值得你十二分努力。