在此之前已有大佬分析过其中lock–unlock实现的机制
https://www.cnblogs.com/java-zhao/p/5131544.html
在这里补充下JNI层面的实现原理
在lock()第二次尝试获取锁时:调用下面的方法
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();//获得锁状态
if (c == 0) {//如果未被占用
if (compareAndSetState(0, acquires)) {//CAS将0置为1
setExclusiveOwnerThread(current);//成功则将当前线程设为独占锁线程
return true;
}
}
else if (current == getExclusiveOwnerThread()) {//如果锁被占用,则判断当前线程是否是独占锁线程
int nextc = c + acquires;//是,则将锁state+1,后面unlock时会逐个-1;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
重点分析 compareAndSetState
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
调用的unsafe类中的compareAndSwapInt 方法
借助C++来调用CPU底层指令实现的;
这个本地方法调用的c++代码为:unsafe.cpp
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
// alternative for InterlockedCompareExchange
int mp = os::is_MP(); //获取当前cpu核数
__asm {
mov edx, dest //目标指针
mov ecx, exchange_value //交换值
mov eax, compare_value //期望值 ,放入寄存器
LOCK_IF_MP(mp) //如何核>1,则加lock
cmpxchg dword ptr [edx], ecx //比较并交换,
}
}