atomic.png
今天在看kafka源碼的時候有這樣一段代碼
val canStartup = isStartingUp.compareAndSet(false, true)
其中上面的 isStartingUp 是 AtomicBoolean
private val isStartingUp = new AtomicBoolean(false)
簡單看一下源碼胁澳,如下:
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ? 1 : 0;
int u = update ? 1 : 0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
其中expect是期望值累魔,update是我們想更新成的值瓮具,最后底層調用的是unsafe的compareAndSwapInt方法,這個是去調用JNI調用C代碼了
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
然后找到JNI的實現(xiàn)代碼
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
核心方法是compxchg钱贯,這個方法所屬的類文件是在OS_CPU目錄下面缔俄,由此可以看出這個類是和CPU操作有關炉媒,進入代碼如下:
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
// alternative for InterlockedCompareExchange
int mp = os::is_MP();
__asm {
mov edx, dest
mov ecx, exchange_value
mov eax, compare_value
LOCK_IF_MP(mp)
cmpxchg dword ptr [edx], ecx
}
}
這個方法里面都是匯編指命,看到LOCK_IF_MP也有鎖指令實現(xiàn)的原子操作驱入,其實CAS也算是有鎖操作赤炒,只不過是由CPU來觸發(fā)氯析,比synchronized性能好的多。