Java高级进阶

2019-08-12-AtomicInteger实现原理

2019-08-12  本文已影响0人  王元

AtomicInteger位于java.util.concurrent.atomic包下,是对int的封装,提供原子性的访问和更新操作,其原子性操作的实现是基于CAS。

包下还有其他的类似原子操作类,AtomicBoolean,AtomicLong等等,大家可以自行查阅,实现的原理都是类似的

都是提供原子性的访问和更新操作,其原子性操作的实现是基于CAS。

1,什么CAS算法

2,CAS的缺点

如果某个线程在CAS操作时发现,内存值和预期值都是A,就能确定期间没有线程对值进行修改吗?答案未必,如果期间发生了 A -> B -> A 的更新,仅仅判断数值是 A,可能导致不合理的修改操作。针对这种情况,Java 提供了 AtomicStampedReference 工具类,通过为引用建立类似版本号(stamp)的方式,来保证 CAS 的正确性。

CAS中使用的失败重试机制,隐藏着一个假设,即竞争情况是短暂的。大多数应用场景中,确实大部分重试只会发生一次就获得了成功。但是总有意外情况,所以在有需要的时候,还是要考虑限制自旋的次数,以免过度消耗 CPU。

3,AtomicInteger原理浅析

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

private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
private static final long VALUE;

static {
    try {
        VALUE = U.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
    } catch (ReflectiveOperationException e) {
        throw new Error(e);
    }
}

private volatile int value;
}

从上面的代码可以看出

下面以getAndIncrement为例,说明其原子操作过程

/**
 * Atomically increments by one the current value.
 *
 * @return the previous value
 */
public final int getAndIncrement() {
    return U.getAndAddInt(this, VALUE, 1);
}

Unsafe的源码

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;
}

参考文章

上一篇 下一篇

猜你喜欢

热点阅读