Java AtomicInteger 类

来源:互联网 发布:好笑的段子 知乎 编辑:程序博客网 时间:2024/05/21 12:44

AtomicInteger是一个提供原子操作处理的类,主要用于高并发环境下进行高效的程序处理,所在的包路径为:java.util.concurrent.atomic。
首先,要说的是,在Java语言中,对数值进行相加或相减的时候,马上会想到用++i 或者 ++、–i 或者 –,事实上这些操作都不是线程安全的,非要使用的话,不可避免地会用到同步关键字synchronize来修饰。
我们来看看对比:

public class MyTest {    private int value;    public MyTest(int value) {        this.value = value;    }    public synchronized int increase() {        return value++;    }    public static void main(String[] args) {        long start = System.currentTimeMillis();        MyTest myTest = new MyTest(0);        for (int i = 0; i < 10000000; i++) {            myTest.increase();        }        long end = System.currentTimeMillis();        System.out.println("执行完成用时:" + (end - start));        //        long start1 = System.currentTimeMillis();        AtomicInteger atomicInteger = new AtomicInteger(0);        for (int i = 0; i < 10000000; i++) {            atomicInteger.incrementAndGet();        }        long end1 = System.currentTimeMillis();        System.out.println("执行完成用时:" + (end1 - start1));    }}
执行的结果:执行完成用时:241执行完成用时:112
其次,我们来看看源代码里提供的方法有哪些:
1、获得当前的最新值    /**     * Gets the current value.     *     * @return the current value     */    public final int get() {        return value;    }2、获得当前的值,并赋予新的一个值    /**     * Atomically sets to the given value and returns the old value.     *     * @param newValue the new value     * @return the previous value     */    public final int getAndSet(int newValue) {        for (;;) {            int current = get();            if (compareAndSet(current, newValue))                return current;        }    }3、取得当前的值,并自增    /**     * Atomically increments by one the current value.     *     * @return the previous value     */    public final int getAndIncrement() {        for (;;) {            int current = get();            int next = current + 1;            if (compareAndSet(current, next))                return current;        }    }4、取得当前的值,并自减    /**     * Atomically decrements by one the current value.     *     * @return the previous value     */    public final int getAndDecrement() {        for (;;) {            int current = get();            int next = current - 1;            if (compareAndSet(current, next))                return current;        }    }5、获得当前的值,并加上预期的值/**     * Atomically adds the given value to the current value.     *     * @param delta the value to add     * @return the previous value     */    public final int getAndAdd(int delta) {        for (;;) {            int current = get();            int next = current + delta;            if (compareAndSet(current, next))                return current;        }    }观察我们得知,以上其中几个方法都调用了这个方法:/**     * Atomically sets the value to the given updated value     * if the current value {@code ==} the expected value.     *     * @param expect the expected value     * @param update the new value     * @return true if successful. False return indicates that     * the actual value was not equal to the expected value.     */    public final boolean compareAndSet(int expect, int update) {        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);    }    /**     * Atomically sets the value to the given updated value     * if the current value {@code ==} the expected value.     *     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>     * and does not provide ordering guarantees, so is only rarely an     * appropriate alternative to {@code compareAndSet}.     *     * @param expect the expected value     * @param update the new value     * @return true if successful.     */    public final boolean weakCompareAndSet(int expect, int update) {        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);    }表面看着方法名不同,实际上调用的方法还是一样的,//使用unsafe的native方法,实现高效的硬件级别CASunsafe.compareAndSwapInt(this, valueOffset, expect, update);关键域有:    // setup to use Unsafe.compareAndSwapInt for updates    private static final Unsafe unsafe = Unsafe.getUnsafe();    private static final long valueOffset;unsafe其实就是java语言提供的获得对象内存地址的访问类,它的实质作用是在更新操作时提供“比较并替换更新”的作用;valueOffset则是用来记录value值本身在内存中的偏移地址,主要是为了在更新操作时候,方便地在内存中找到value的位置,然后进行比较。注意:value是用来存储整数的时间变量,这里被声明为volatile,就是为了保证在更新操作时,当前线程可以拿到value最新的值(并发环境下,value可能已经被其他线程更新了)。

网上的参考资料:
1)Java 理论与实践: 流行的原子
http://www.ibm.com/developerworks/cn/java/j-jtp11234/
2)
http://stackoverflow.com/questions/2443239/how-can-weakcompareandset-fail-spuriously-if-it-is-implemented-exactly-like-comp

0 0
原创粉丝点击