Java可重入鎖的實(shí)現(xiàn)原理與應(yīng)用場(chǎng)景
可重入鎖,從字面來理解,就是可以重復(fù)進(jìn)入的鎖。
可重入鎖,也叫做遞歸鎖,指的是同一線程外層函數(shù)獲得鎖之后,內(nèi)層遞歸函數(shù)仍然有獲取該鎖的代碼,但不受影響。
在JAVA環(huán)境下ReentrantLock
和synchronized
都是可重入鎖。
synchronized
是一個(gè)可重入鎖。在一個(gè)類中,如果synchronized方法1調(diào)用了synchronized方法2,方法2是可以正常執(zhí)行的,這說明synchronized是可重入鎖。否則,在執(zhí)行方法2想獲取鎖的時(shí)候,該鎖已經(jīng)在執(zhí)行方法1時(shí)獲取了,那么方法2將永遠(yuǎn)得不到執(zhí)行。
可重入鎖在什么場(chǎng)景使用呢?
可重入鎖主要用在線程需要多次進(jìn)入臨界區(qū)代碼時(shí),需要使用可重入鎖。具體的例子,比如上文中提到的一個(gè)synchronized方法需要調(diào)用另一個(gè)synchronized方法時(shí)。
可重入鎖的實(shí)現(xiàn)原理是怎么樣的?
加鎖時(shí),需要判斷鎖是否已經(jīng)被獲取。如果已經(jīng)被獲取,則判斷獲取鎖的線程是否是當(dāng)前線程。如果是當(dāng)前線程,則給獲取次數(shù)加1。如果不是當(dāng)前線程,則需要等待。
釋放鎖時(shí),需要給鎖的獲取次數(shù)減1,然后判斷,次數(shù)是否為0了。如果次數(shù)為0了,則需要調(diào)用鎖的喚醒方法,讓鎖上阻塞的其他線程得到執(zhí)行的機(jī)會(huì)。
下面是一個(gè)用synchronized實(shí)現(xiàn)的例子:
public class ReentrantTest implements Runnable { public synchronized void get() { System.out.println(Thread.currentThread().getName()); set(); } public synchronized void set() { System.out.println(Thread.currentThread().getName()); } public void run() { get(); } public static void main(String[] args) { ReentrantTest rt = new ReentrantTest(); for(;;){ new Thread(rt).start(); } } }
整個(gè)過程沒有發(fā)生死鎖的情況,截取一部分輸出結(jié)果如下:
Thread-8492
Thread-8492
Thread-8494
Thread-8494
Thread-8495
Thread-8495
Thread-8493
Thread-8493
set()
和get()
同時(shí)輸出了線程名稱,表明即使遞歸使用synchronized
也沒有發(fā)生死鎖,證明其是可重入的。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
springCloud服務(wù)注冊(cè)Eureka實(shí)現(xiàn)過程圖解
這篇文章主要介紹了springCloud服務(wù)注冊(cè)Eureka實(shí)現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Spring Boot 各種回滾操作實(shí)戰(zhàn)教程(自動(dòng)回滾、手動(dòng)回滾、部分回滾)
這篇文章主要介紹了Spring Boot 各種回滾操作實(shí)戰(zhàn)教程(自動(dòng)回滾、手動(dòng)回滾、部分回滾),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07Java Lock接口實(shí)現(xiàn)原理及實(shí)例解析
這篇文章主要介紹了Java Lock接口實(shí)現(xiàn)原理及實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04springboot整合通用Mapper簡(jiǎn)化單表操作詳解
這篇文章主要介紹了springboot整合通用Mapper簡(jiǎn)化單表操作,通用Mapper是一個(gè)基于Mybatis,將單表的增刪改查通過通用方法實(shí)現(xiàn),來減少SQL編寫的開源框架,需要的朋友可以參考下2019-06-06Java通過PowerMockito和Mokito進(jìn)行單元測(cè)試的實(shí)現(xiàn)
PowerMockito和Mockito都是Java語言中的測(cè)試框架,用于進(jìn)行單元測(cè)試和集成測(cè)試,本文就來詳細(xì)的介紹一下通過PowerMockito和Mokito進(jìn)行單元測(cè)試,感興趣的可以了解一下2023-08-08