..
Juc 1
本章主要介绍JUC包当中的一些并发处理
cas
/**
* Atomically update Java variable to <tt>x</tt> if it is currently
* holding <tt>expected</tt>.
* @return <tt>true</tt> if successful
*/
public final native boolean compareAndSwapInt(Object o, long offset,
int expected,
int x);
上面的代码大家可能都比较熟悉,是Unsafe下的对于int属性的cas操作。native方法我们直接去JNI查找实现
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);
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END
上面的代码主要分为3步骤
- 根据对象获取oop描述信息
- 根据偏移量获取绝对地址
- 执行cas原子操作
本文只对步骤3进行讨论
我们能看到很多处理器下的实现 在此我们只聚焦于X86
#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "cc", "memory");
return exchange_value;
}
以上代码是先判断当前机器是否为多核处理器并存储在mp变量当中。然后作为入参执行内联汇编。 LOCK_IF_MP判断如果是多处理器则插入 LOCK 指令。然后执行 cmpxchgl 进行比较并交换。