獨佔鎖的正常使用方式,先從加鎖邏輯開始。
reentrantlock分lock lock =
newreentrantlock()
;public
void
test()
finally
}
公平鎖和非公平鎖
,公平鎖指搶鎖的執行緒進來先入佇列排隊,按照fifo的方式獲取鎖。而非公平鎖指執行緒開始可以插隊嘗試獲取鎖,如果獲取失敗,才入佇列排隊,接著按照fifo的方式獲取鎖。其實非公平鎖的後一部分邏輯和公平鎖一樣,下面以非公平鎖分析。
下面接著看acquire(1):final
void
lock()
下面把acquire(int arg)下的幾個方法拆開來看:public
final
void
acquire
(int arg)
protected
final
boolean
tryacquire
(int acquires)
分析完了acquire(1),接下來分析addwaiter(node.exclusive),走到這裡說明鎖被其他執行緒拿去了:final
boolean
nonfairtryacquire
(int acquires)
}//如果c!=0,判斷持有鎖的執行緒是否是當前執行緒,這裡支援鎖的可重入性
else
if(current ==
getexclusiveownerthread()
)//拿鎖失敗
return
false
;}
private node addwaiter
(node mode)
}//如果走到這裡,說明更新尾節點失敗,進入自旋,不斷嘗試將自己新增到尾節點
enq(node)
;return node;
}
這時候已經將新節點新增到佇列尾部了,接下來往下看:private node enq
(final node node)
else}}
}
下面是掛起邏輯://node就是新加進去的尾節點
final
boolean
acquirequeued
(final node node,
int arg)if(
shouldparkafte***iledacquire
(p, node)
&&parkandcheckinterrupt()
) interrupted =
true;}
}finally
}
在上述**中返回true後,下面是真正的掛起邏輯,將當前執行緒掛起,避免無休止的自旋消耗cpu資源。注意,後面將喚醒已掛起的執行緒的時候,從這裡開始喚醒,成功獲取鎖,走完lock.lock()方法,進入業務**:private
static
boolean
shouldparkafte***iledacquire
(node pred, node node)
while
(pred.waitstatus >0)
; pred.next = node;
}else
//返回false後會進入for(;;)的下一次自旋
return
false
;}
釋放鎖的邏輯,無**平鎖還是非公平鎖都是一樣的。private
final
boolean
parkandcheckinterrupt()
public
void
unlock()
嘗試釋放鎖://釋放鎖
public
final
boolean
release
(int arg)
return
false
;}
喚醒後繼節點:protected
final
boolean
tryrelease
(int releases)
setstate
(c);
//標誌是否釋放了鎖
return free;
}
private
void
unparksuccessor
(node node)
//喚醒執行緒
if(s != null)
locksupport.
unpark
(s.thread)
;}
在獲取同步狀態時,同步器維護乙個同步佇列,獲取狀態失敗的執行緒都會被加入到佇列中並在佇列中進行自旋;移出佇列(或停止自旋)的條件是前驅節點為頭節點且成功獲取了同步狀態。在釋放同步狀態時,同步器呼叫tryrelease(int arg)方法釋放同步狀態,然後喚醒head指向節點的後繼節點。
節點加入到鍊錶尾部和從鍊錶移出示意圖通過上面的原始碼分析,結合下圖理解。
節點加入到鍊錶尾部:
節點從鍊錶移除:
獨佔式同步狀態獲取與釋放流程圖:
併發程式設計核心框架AQS之獨佔鎖原理詳解
如何設計符合冪等性的高質量restful api 理解restful的冪等性,並且設計符合冪等規範的高質量restful api。http冪等方法,是指無論呼叫多少次都不會有不同結果的 http 方法。不管你呼叫一次,還是呼叫一百次,一千次,結果都是相同的。還是以之前的博文的例子為例。get tic...
JUC併發基石之AQS原始碼解析 獨佔鎖的釋放
juc併發基石之aqs原始碼解析 獨佔鎖的獲取public final boolean release int arg return false 獨佔鎖的涉及到兩個函式的呼叫 1.tryrelease arg 該方法由aqs的子類來實現釋放鎖的具體邏輯 2.unparksuccessor h 喚醒後...
AQS共享鎖的實現原理
前面的文章lock的實現中分析了aqs獨佔鎖的實現原理,那麼接下來就分析下aqs是如何實現共享鎖的。共享鎖的介紹 共享鎖 同一時刻有多個執行緒能夠獲取到同步狀態。那麼它是如何做到讓多個執行緒獲取到同步狀態呢?來看一下獲取共享鎖的過程 1.執行緒呼叫aqs的acquireshared 申請獲取鎖 可有...