Java AtomicInteger 类

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方法,实现高效的硬件级别CAS
unsafe.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值