ReentrantLock可重入鎖原理解析
ReentrantLock 可重入鎖
字面意思理解為同一線程可以重入加鎖
內(nèi)部主要邏輯繼承AQS來實現(xiàn)的,有兩種實現(xiàn)FairSycn、NonfairSync,公平鎖和非公平鎖,默認為非公平鎖。
- 公平鎖:保證先入隊的先獲得鎖。
- 非公平鎖:不保證先入隊的先獲得鎖,可能后面的線程先搶到鎖。

主要實現(xiàn)流程

CAS全名compare and swap比較交換,由native方法提供的系統(tǒng)原子性操作,以保證并發(fā)發(fā)安全性。
公平鎖的實現(xiàn)
加鎖
//加鎖
final void lock() {
acquire(1);//調(diào)用AQS方法
}//AQS方法
public final void acquire(int arg) {
if (!tryAcquire(arg) &&//嘗試獲取鎖,抽象方法由子類實現(xiàn)
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
/* addWaiter 將線程加入等待隊列
* acquireQueued 嘗試獲取鎖、阻塞
*/
{
//中斷
selfInterrupt();
}
}//嘗試獲取鎖
protected final boolean tryAcquire(int acquires) {
//獲取當前線程
final Thread current = Thread.currentThread();
int c = getState();//獲取state值,AQS屬性volatile標記
if (c == 0) {//鎖空閑狀態(tài)
if (!hasQueuedPredecessors() &&//是否需要排隊
compareAndSetState(0, acquires)) {//獲取鎖
setExclusiveOwnerThread(current);//成功獲取,設(shè)置鎖owner為當前線程
return true;//后續(xù)不在處理
}
}
else if (current == getExclusiveOwnerThread()) {//當前線程已持有鎖,重入
int nextc = c + acquires;//state+1
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);//已持有鎖,直接設(shè)置state值
return true;
}
return false;
}解鎖
//解鎖,ReentrantLock方法
public void unlock() {
sync.release(1);//AQS方法
}//AQS解鎖
public final boolean release(int arg) {
if (tryRelease(arg)) {//嘗試解鎖
Node h = head;
if (h != null && h.waitStatus != 0)//waitStatus=0時不進行unpark(喚醒),next線程可能中斷
unparkSuccessor(h);//喚醒隊列中的線程去獲取鎖
return true;
}
return false;
}//嘗試解鎖ReentrantLock內(nèi)部靜態(tài)類Sync實現(xiàn)
protected final boolean tryRelease(int releases) {
int c = getState() - releases;//state-1
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();//非持有鎖的線程進行釋放,非法操作
boolean free = false;
if (c == 0) {//持有鎖線程全部釋放
free = true;
setExclusiveOwnerThread(null);//持有鎖線程置空
}
setState(c);//持有鎖線程直接設(shè)置state
return free;
}非公平鎖的實現(xiàn)
非公平鎖和公平鎖的核心區(qū)別是在嘗試獲取鎖方法tryAcquire實現(xiàn)中沒有判斷hasQueuedPredecessors()是否需要排隊,其他邏輯和公平鎖是一致的。

以上就是ReentrantLock可重入鎖原理解析的詳細內(nèi)容,更多關(guān)于ReentrantLock可重入鎖的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java replaceAll()方法報錯Illegal group reference的解決辦法
這篇文章主要給大家介紹了關(guān)于Java replaceAll()方法報錯Illegal group reference的解決辦法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09
javaSE基礎(chǔ)如何通俗的理解javaBean是什么
所謂的Java Bean,就是一個java類,編譯后成為了一個后綴名是 .class的文件。這就是Java Bean,很多初學者,包括當年的我自己,總是被這些專有名詞搞的暈頭轉(zhuǎn)向2021-10-10
使用Java進行FreeMarker的web模板開發(fā)的基礎(chǔ)教程
這篇文章主要介紹了使用Java進行FreeMarker模板引擎開發(fā)的基礎(chǔ)教程,文中針對FreeMarker的網(wǎng)頁標簽用法給出了一些例子,需要的朋友可以參考下2016-03-03
idea的easyCode的 MybatisPlus模板的配置詳解
這篇文章主要介紹了idea的easyCode的 MybatisPlus模板的配置詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09
實例詳解Spring Boot實戰(zhàn)之Redis緩存登錄驗證碼
本章簡單介紹redis的配置及使用方法,本文示例代碼在前面代碼的基礎(chǔ)上進行修改添加,實現(xiàn)了使用redis進行緩存驗證碼,以及校驗驗證碼的過程。感興趣的的朋友一起看看吧2017-08-08

