java 可重入鎖ReentrantLock的介紹


一個小例子幫助理解(我們常用的synchronized也是可重入鎖)

話說從前有一個村子,在這個村子中有一口水井,家家戶戶都需要到這口井里打水喝。由於井水有限,大家只能依次打水。為了實現家家有水喝,戶戶有水用的目標,村長絞盡腦汁,最終想出了一個比較合理的方案。

首先,在水井邊上安排一個看井人,負責維持秩序。

然后,打水時,以家庭為單位,哪個家庭任何人先到井邊,就可以先打水,而且如果一個家庭占到了打水權,其家人這時候過來打水不用排隊。而那些沒有搶占到打水權的人,一個一個挨着在井邊排成一隊,先到的排在前面。

最后,打水的人打完水以后就告訴看井人,看井人就讓等待的隊伍中的最前面一個去打水。

這樣一來,大家都能打到水,也保證了相對的公平。這就是公平鎖的基本思路。

隨着時間的推移,村民發現每次去打水的時候都需要排隊,想着每次排隊都浪費時間,於是就把水桶放在井邊代替,自己則溜回家去了。這樣一搞,可把看井人累壞,經常往村民家里跑,讓他們來打水。於是聰明的看井人想出了一個對策,如果有人打完水后,剛好又有其它人來打水,就直接讓這個新來的人上去打水,不用到隊伍末尾去排隊等候。

這種方式雖然看上去不公平,但是他節省了資源,提高了打水的性能,這就是非公平鎖的基本思路。

打水的小故事在java中的應用

Java中可重入鎖-ReentrantLock基本上就是按照上面的思路來實現的,我們來對給他們做一個簡單的對比。

一次只有一個人能打水 鎖需要保證多線程的同步。

必須嚴格按照排隊順序打水 ReentrantLock提供的公平鎖功能。

來得早不如來得巧 ReentrantLock提供的非公平鎖功能。

有家人正在打水的時候就不需要排隊 ReentrantLock的可重入特性。

那么可重入鎖又是怎樣實現上面那些特性的呢?

java可重入鎖-ReentrantLock實現細節

首先我們從上面的故事入手,看看ReentrantLock中的各個角色都是怎么樣的。

打水權 volatile int state

打水者 線程、Thread

打水隊伍 雙向鏈表Node

獲取鎖的時候,公平鎖的整個工作流程就如下圖所示:

可重入公平鎖獲取流程

在獲取鎖的時候,如果當前線程之前已經獲取到了鎖,就會把state加1,在釋放鎖的時候會先減1,這樣就保證了同一個鎖可以被同一個線程獲取多次,而不會出現死鎖的情況。這就是ReentrantLock的可重入性。

對於非公平鎖而言,調用lock方法后,會先嘗試搶占鎖,在各種判斷的時候會先忽略等待隊列,如果鎖可用,就會直接搶占使用。

釋放鎖的時候,整個工作流程如下圖:

可重入鎖釋放過程

本文為轉載:https://baijiahao.baidu.com/s?id=1594800969528243663&wfr=spider&for=pc
參考:https://blog.csdn.net/yanyan19880509/article/details/52345422


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM