CAS实现原理

protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

通过 cas 乐观锁的方式来做比较并替换,这段代码的意思是,如果当前内存中的 state的值和预期值expect相等,则替换为update。
更新成功返回true,否则返 回false. 这个操作是原子的,不会出现线程安全问题,这里面涉及到Unsafe这个类的操作

Unsafe 类
Unsafe类是在sun.misc包下,不属于Java标准。但是很多Java的基础类库,包 括一些被广泛使用的高性能开发库都是基于 Unsafe 类开发的,
比如 Netty、 Hadoop、Kafka等; Unsafe 可认为是 Java 中留下的后门,
提供了一些低层次操作,如直接内存访问、 线程的挂起和恢复、CAS、线程同步、内存屏障 而 CAS 就是 Unsafe 类中提供的一个原子操作,第一个参数为需要改变的对象,
第二个为偏移量(即之前求出来的 headOffset 的值),第三个参数为期待的值,第 四个为更新后的值整个方法的作用是如果当前时刻的值等于预期值var4相等,则
更新为新的期望值 var5,
如果更新成功,则返回true,否则返回false;

stateOffset
一个Java对象可以看成是一段内存,每个字段都得按照一定的顺序放在这段内存 里,通过这个方法可以准确地告诉你某个字段相对于对象的起始内存地址的字节 偏移。
用于在后面的compareAndSwapInt中,
去根据偏移量找到对象在内存中的 具体位置 所以stateOffset表示state这个字段在AQS类的内存中相对于该类首地址的偏移 量

compareAndSwapInt
在unsafe.cpp文件中,可以找到compareAndSwarpInt的实现
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset,

jint e, jint x))   UnsafeWrapper("Unsafe_CompareAndSwapInt");  
oop p = JNIHandles::resolve(obj);  //将Java对象解析成JVM的oop(普通对象指针),  
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); //根据对象p和地址偏移量找到地址  
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
//基于cas比较并替换,
x表示需要更新的值,addr表示state 在内存中的地址,e表示预期值 UNSAFE_END
posted @ 2020-06-25 12:06  zpp13  阅读(148)  评论(0编辑  收藏  举报