Java中GetAndAdd函数

来源:互联网 发布:java链表 编辑:程序博客网 时间:2024/06/16 03:25

GetAndAdd

解释:以原子方式将给定值与当前值相加;

源码:

 public final int getAndAdd(int delta) {     return unsafe.getAndAddIn(this,valueOffset,delta); }

补充(原子更新基本类型):

  • AtomicBoolean:原子更新布尔变量;

  • AtomicInteger:原子更新整型变量;

  • AtomicLong:原子更新长整型变量;

这里以AtomicInteger为例进行说明,AtomicInteger提供的部分方法如下:

 public class AtomicInteger extends Number implements java.io.Serializable {     //返回当前的值     public final int get() {         return value;     }     //原子更新为新值并返回旧值     public final int getAndSet(int newValue) {         return unsafe.getAndSetInt(this, valueOffset, newValue);     }     //最终会设置成新值     public final void lazySet(int newValue) {         unsafe.putOrderedInt(this, valueOffset, newValue);     }     //如果输入的值等于预期值,则以原子方式更新为新值     public final boolean compareAndSet(int expect, int update) {         return unsafe.compareAndSwapInt(this, valueOffset, expect, update);     }     //原子自增     public final int getAndIncrement() {         return unsafe.getAndAddInt(this, valueOffset, 1);     }     //原子方式将当前值与输入值相加并返回结果     public final int getAndAdd(int delta) {         return unsafe.getAndAddInt(this, valueOffset, delta);     } }

为了说明AtomicInteger的原子性,这里代码演示多线程对一个int值进行自增操作,最后输出结果,代码如下:

package com.rhwayfun.concurrency.r0405;import java.util.concurrent.atomic.AtomicInteger;/*** Created by rhwayfun on 16-4-5.*/public class AtomicIntegerDemo {    private static AtomicInteger atomicInteger = new AtomicInteger(0);    public static void main(String[] args){        for (int i = 0; i < 5; i++){            new Thread(new Runnable() {                public void run() {                    //调用AtomicInteger的getAndIncement返回的是增加之前的值                     System.out.println(atomicInteger.getAndIncrement());                }            }).start();        }        System.out.println(atomicInteger.get());    }}

输出结果如下:

    0    1    2    3    4    5    5

可以看到在多线程的情况下,得到的结果是正确的,但是如果仅仅使用int类型的成员变量则可能得到不同的结果。这里的关键在于getAndIncrement是原子操作,那么是如何保证的呢?

getAndIncrement方法的源码如下:

public final int getAndIncrement() {    return unsafe.getAndAddInt(this, valueOffset, 1);}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;}public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

到这里可以发现最终调用了native方法来保证更新的原子性。


参考博客:
http://http://blog.csdn.net/u011116672/article/details/51068828

8/16/2017 10:57:06 PM

原创粉丝点击