Java -- 每日一问:AtomicInteger底层实现原理是什么?如何在自己的产品代码中应用CAS操作?

Posted Kevin-Dev

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java -- 每日一问:AtomicInteger底层实现原理是什么?如何在自己的产品代码中应用CAS操作?相关的知识,希望对你有一定的参考价值。

经典回答

AtomicIntger 是对 int 类型的一个封装,提供原子性的访问和更新操作,其原子性操作的实现是基于 CAS(compare-and-swap)技术。

所谓 CAS,表征的是一系列操作的集合,获取当前数值,进行一些运算,利用 CAS 指令试图进行更新。如果当前数值未变,代表没有其他线程进行并发修改,则成功更新。否则,可能出现不同的选择,要么进行重试,要么就返回一个成功或者失败的结果。

从 AtomicInteger 的内部属性可以看出,它依赖于 Unsafe 提供的一些底层能力,进行底层操作;以 volatile 的 value 字段,记录数值,以保证可见性。

private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value");
private volatile int value;

具体的原子操作细节,可以参考任意一个原子更新方法,比如下面的 getAndIncrement。

Unsafe 会利用 value 字段的内存地址偏移,直接完成操作。

public final int getAndIncrement()  
    return U.getAndAddInt(this, VALUE, 1);

因为 getAndIncrement 需要返归数值,所以需要添加失败重试逻辑。

public final int getAndAddInt(Object o, long offset, int delta) 
     int v; 
    do  
        v = getIntVolatile(o, offset);
      while (!weakCompareAndSetInt(o, offset, v, v + delta)); 
    return v;

而类似 compareAndSet 这种返回 boolean 类型的函数,因为其返回值表现的就是成功与否,所以不需要重试。

public final boolean compareAndSet(int expectedValue, int newValue)

CAS 是 Java 并发中所谓 lock-free 机制的基础。

你的朋友是不是也在准备面试呢?你可以“请朋友读”,把今天的题目分享给好友,或许你能帮到他。

以上是关于Java -- 每日一问:AtomicInteger底层实现原理是什么?如何在自己的产品代码中应用CAS操作?的主要内容,如果未能解决你的问题,请参考以下文章

Java -- 每日一问:谈谈你对 Java 平台的理解?

Java -- 每日一问:Exception 和 Error 有什么区别?

Java -- 每日一问:Exception 和 Error 有什么区别?

Java -- 每日一问:如何写出安全的 Java 代码?

Java -- 每日一问:synchronized和ReentrantLock有什么区别呢?

Java -- 每日一问:Java并发包提供了哪些并发工具类?