1. cas
1.1什么是cas
CAS: 全称Compare andswap,字面意思:”比较并交换“,一个 CAS 涉及到以下操作:
我们假设内存中的原数据V,旧的预期值A(对象栈中存放的值),需要修改的新值B。
(1) 比较 A 与 V 是否相等。(比较)
(2)如果比较相等,将 B 写入 V。(交换)
(3)返回操作是否成功。
1.2 CAS 是怎么实现的
跟随AtomInteger的代码我们一路往下,就能发现最终调用的是 sum.misc.Unsafe 这个类。看名称 Unsafe 就是一个不安全的类,这个类是利用了 Java 的类和包在可见性的的规则中的一个恰到好处处的漏洞。Unsafe 这个类为了速度,在Java的安全标准上做出了一定的妥协。
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5); |
注释:native表示的方法表示调用操作系统底层的方法
在OPENJDK中/jdk9u/hotspot/src/share/vm/unsafe.cpp找到
{CC "compareAndSetInt", CC "(" OBJ "J""I""I"")Z", FN_PTR(Unsafe_CompareAndSetInt)}, |
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) { oop p = JNIHandles::resolve(obj); jint* addr = (jint *)index_oop_from_field_offset_long(p, offset); return (jint)(Atomic::cmpxchg(x, addr, e)) == e; } UNSAFE_END |
最终我们终于看到了核心代码Atomic::cmpxchg。
1.3总结
关于 CAS 的底层探索我们就到此为止。我们总结一下 JAVA 的 cas 是怎么实现的:
(1)java 的 cas 利用的的是 unsafe 这个类提供的 cas 操作。
(2)unsafe 的cas 依赖了的是 jvm 针对不同的操作系统实现的Atomic::cmpxchg
(3)Atomic::cmpxchg的实现使用了汇编的 cas 操作,并使用 cpu 硬件提供的 lock信号保证其原子性。