Java并發(fā)編程中的ReentrantLock類詳解
一、ReentrantLock介紹
ReentrantLock是juc.locks包中的一個獨占式可重入鎖,相比synchronized,它可以創(chuàng)建多個條件等待隊列,還支持公平/非公平鎖、可中斷、超時、輪詢等特性。
ReentrantLock實現(xiàn)Lock接口實現(xiàn)了一個鎖所需的方法,如lock()、unLock()等,在這些方法中實際上是調(diào)用繼承了AQS的同步器Sync對象中的方法來實現(xiàn)對鎖資源的獲取與釋放,而內(nèi)部類Sync有兩個子類FairSync和NonfairSync,分別對應(yīng)公平鎖和非公平鎖。ReentrantLock默認(rèn)構(gòu)造器是構(gòu)造非公平鎖



二、ReentrantLock特性詳解
1. 多條件隊列
Sync對象中開放了創(chuàng)建AQS中條件隊列ConditionObject對象的方法,并重寫了isHeldExclusively()方法(通知方法signal()要用到),因此可創(chuàng)建條件隊列實現(xiàn)通知等待機(jī)制。

2. 非公平 & 公平鎖
非公平鎖NonfairSync 新進(jìn)來的線程會先直接與同步隊列中的線程競爭CAS競爭失敗則調(diào)用acquire -> tryAcquire -> nonfairTryAcquire繼續(xù)競爭,再失敗才會在acquire方法中后續(xù)執(zhí)行加入同步隊列若線程是重入這個鎖,會記錄重入次數(shù),若超過int范圍溢出則拋出錯誤


公平鎖FairSync 新來的線程若同步隊列為空才競爭鎖,否則tryAcquire直接返回false然后進(jìn)入隊列排隊,實現(xiàn)先來后到公平鎖同樣也會記錄重入次數(shù)

3. 可中斷
我們知道synchronized在鎖競爭時是不可中斷的,獲取不到鎖的線程會一直處于阻塞狀態(tài)。
而ReentrantLock調(diào)用lockInterruptibly()獲取鎖的過程是可以響應(yīng)中斷的,其內(nèi)部調(diào)用的是AQS的acquireInterruptibly()方法
當(dāng)收到中斷信號時會退出阻塞然后拋出InterruptedException異常從而退出鎖競爭。
4. 超時
調(diào)用tryLock(long timeout, TimeUnit unit)獲取鎖可實現(xiàn)超時功能,當(dāng)超過時間還未獲取到鎖則直接拋出異常退出鎖競爭

內(nèi)部是AQS中調(diào)用LockSupport.parkNanos()超時阻塞實現(xiàn)的
5. 輪詢
ReentrantLock的輪詢特性是指可通過tryLock()方法嘗試獲取鎖,沒獲取到則不阻塞直接退出,可以過會再來嘗試。tryLock()調(diào)用Sync中定義的nonfairTryAcquire方法,從前面列出的源碼可知沒獲取到則直接返回false

三、ReentrantLock類和synchronized關(guān)鍵字的區(qū)別
ReentrantLock和synchronized都是獨占式可重入鎖,但是它們有如下區(qū)別:
- 鎖實現(xiàn)機(jī)制:ReentrantLock是一個類,是基于AQS實現(xiàn)的,依賴于JDK的API;synchronized是一個關(guān)鍵字,是直接在JVM層面通過監(jiān)視器實現(xiàn)的鎖機(jī)制。
- 條件等待隊列:ReentrantLock通過Condition可創(chuàng)建多個條件等待隊列;而synchronized依賴的監(jiān)視器模型中只有一個等待隊列。
- 非公平 & 公平鎖:ReentrantLock支持公平和非公平鎖;synchronized為非公平鎖
- 其他特性:ReentrantLock還支持可中斷、超時、輪詢等特性;synchronized不支持這些
- 底層原理:ReentrantLock是基于CAS實現(xiàn)共享資源同步,synchronized底層是基于互斥量實現(xiàn)的
一般來說在不需要用到ReentrantLock特殊特性的時候就用synchronized,因為synchronized顯然相對來說使用起來更加簡潔高效
到此這篇關(guān)于Java并發(fā)編程中的ReentrantLock類詳解的文章就介紹到這了,更多相關(guān)Java的ReentrantLock類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
掌握這4個配置點輕輕松松實現(xiàn)VSCode多JDK版本自由切換
眾所周知在VSCode中切換JDK版本可以通過多種方式實現(xiàn),具體取決于你使用的開發(fā)環(huán)境和項目類型,這篇文章主要介紹了如何實現(xiàn)VSCode多JDK版本自由切換的相關(guān)資料,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下2026-02-02
Java查詢緩存之優(yōu)化重復(fù)查詢的執(zhí)行效率問題
這篇文章主要介紹了Java查詢緩存之優(yōu)化重復(fù)查詢的執(zhí)行效率問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-05-05
Springboot整合logback多節(jié)點日志文件加端口號區(qū)分的操作方法
這篇文章主要介紹了Springboot整合logback多節(jié)點日志文件加端口號區(qū)分的操作方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09
Java動態(tài)代理機(jī)制詳解_動力節(jié)點Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Java動態(tài)代理機(jī)制,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
詳解Java中多線程異常捕獲Runnable的實現(xiàn)
這篇文章主要介紹了詳解Java中多線程異常捕獲Runnable的實現(xiàn)的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這樣的知識,需要的朋友可以參考下2017-10-10

