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



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

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


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

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

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

三、ReentrantLock類(lèi)和synchronized關(guān)鍵字的區(qū)別
ReentrantLock和synchronized都是獨(dú)占式可重入鎖,但是它們有如下區(qū)別:
- 鎖實(shí)現(xiàn)機(jī)制:ReentrantLock是一個(gè)類(lèi),是基于A(yíng)QS實(shí)現(xiàn)的,依賴(lài)于JDK的API;synchronized是一個(gè)關(guān)鍵字,是直接在JVM層面通過(guò)監(jiān)視器實(shí)現(xiàn)的鎖機(jī)制。
- 條件等待隊(duì)列:ReentrantLock通過(guò)Condition可創(chuàng)建多個(gè)條件等待隊(duì)列;而synchronized依賴(lài)的監(jiān)視器模型中只有一個(gè)等待隊(duì)列。
- 非公平 & 公平鎖:ReentrantLock支持公平和非公平鎖;synchronized為非公平鎖
- 其他特性:ReentrantLock還支持可中斷、超時(shí)、輪詢(xún)等特性;synchronized不支持這些
- 底層原理:ReentrantLock是基于CAS實(shí)現(xiàn)共享資源同步,synchronized底層是基于互斥量實(shí)現(xiàn)的
一般來(lái)說(shuō)在不需要用到ReentrantLock特殊特性的時(shí)候就用synchronized,因?yàn)閟ynchronized顯然相對(duì)來(lái)說(shuō)使用起來(lái)更加簡(jiǎn)潔高效
到此這篇關(guān)于Java并發(fā)編程中的ReentrantLock類(lèi)詳解的文章就介紹到這了,更多相關(guān)Java的ReentrantLock類(lèi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java多線(xiàn)程并發(fā)JUC包ReentrantLock顯示鎖的用法
- Java使用ReentrantLock進(jìn)行加解鎖的示例代碼
- Java中的Lock與ReentrantLock深入解析
- Java中的ReentrantLock實(shí)現(xiàn)原理及代碼演示
- Java可重入鎖reentrantLock解析
- Java并發(fā)編程之ReentrantLock解析
- Java并發(fā)編程中的ReentrantLock詳解
- Java中的ReentrantLock原理解析
- 淺談一下Java中的ReentrantLock
- Java ReentrantLock的使用與應(yīng)用實(shí)戰(zhàn)
相關(guān)文章
Java回調(diào)函數(shù)與觀(guān)察者模式實(shí)例代碼
這篇文章主要介紹了Java回調(diào)函數(shù)與觀(guān)察者模式實(shí)例代碼,簡(jiǎn)單介紹了使用觀(guān)察者模式的場(chǎng)景,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02
Java IO流對(duì)象的序列化和反序列化實(shí)例詳解
這篇文章主要介紹了Java IO流對(duì)象的序列化和反序列化實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05
Spring Boot應(yīng)用啟動(dòng)時(shí)自動(dòng)執(zhí)行代碼的五種方式(常見(jiàn)方法)
Spring Boot為開(kāi)發(fā)者提供了多種方式在應(yīng)用啟動(dòng)時(shí)執(zhí)行自定義代碼,這些方式包括注解、接口實(shí)現(xiàn)和事件監(jiān)聽(tīng)器,本文我們將探討一些常見(jiàn)的方法,以及如何利用它們?cè)趹?yīng)用啟動(dòng)時(shí)執(zhí)行初始化邏輯,感興趣的朋友一起看看吧2024-04-04
解讀CommandLineRunner和@PostConstruct區(qū)別與應(yīng)用場(chǎng)景
這篇文章主要介紹了解讀CommandLineRunner和@PostConstruct區(qū)別與應(yīng)用場(chǎng)景,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Java下載遠(yuǎn)程服務(wù)器文件到本地(基于http協(xié)議和ssh2協(xié)議)
這篇文章主要介紹了Java下載遠(yuǎn)程服務(wù)器文件到本地的方法(基于http協(xié)議和ssh2協(xié)議),幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2021-01-01
POI導(dǎo)出Excel報(bào)錯(cuò)No such file or directory的解決方法
這篇文章主要為大家詳細(xì)介紹了POI導(dǎo)出Excel報(bào)錯(cuò)No such file or directory的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11

