Java可重入鎖的實現(xiàn)原理與應(yīng)用場景
可重入鎖,從字面來理解,就是可以重復(fù)進(jìn)入的鎖。
可重入鎖,也叫做遞歸鎖,指的是同一線程外層函數(shù)獲得鎖之后,內(nèi)層遞歸函數(shù)仍然有獲取該鎖的代碼,但不受影響。
在JAVA環(huán)境下ReentrantLock和synchronized都是可重入鎖。
synchronized是一個可重入鎖。在一個類中,如果synchronized方法1調(diào)用了synchronized方法2,方法2是可以正常執(zhí)行的,這說明synchronized是可重入鎖。否則,在執(zhí)行方法2想獲取鎖的時候,該鎖已經(jīng)在執(zhí)行方法1時獲取了,那么方法2將永遠(yuǎn)得不到執(zhí)行。
可重入鎖在什么場景使用呢?
可重入鎖主要用在線程需要多次進(jìn)入臨界區(qū)代碼時,需要使用可重入鎖。具體的例子,比如上文中提到的一個synchronized方法需要調(diào)用另一個synchronized方法時。
可重入鎖的實現(xiàn)原理是怎么樣的?
加鎖時,需要判斷鎖是否已經(jīng)被獲取。如果已經(jīng)被獲取,則判斷獲取鎖的線程是否是當(dāng)前線程。如果是當(dāng)前線程,則給獲取次數(shù)加1。如果不是當(dāng)前線程,則需要等待。
釋放鎖時,需要給鎖的獲取次數(shù)減1,然后判斷,次數(shù)是否為0了。如果次數(shù)為0了,則需要調(diào)用鎖的喚醒方法,讓鎖上阻塞的其他線程得到執(zhí)行的機會。
下面是一個用synchronized實現(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();
}
}
}
整個過程沒有發(fā)生死鎖的情況,截取一部分輸出結(jié)果如下:
Thread-8492
Thread-8492
Thread-8494
Thread-8494
Thread-8495
Thread-8495
Thread-8493
Thread-8493
set()和get()同時輸出了線程名稱,表明即使遞歸使用synchronized也沒有發(fā)生死鎖,證明其是可重入的。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
相關(guān)文章
SpringBoot項目打包成war包并部署在tomcat上運行的操作步驟
我們開發(fā) SpringBoot 項目有時我們會需要打包成 war 包,放入外置的 Tomcat 中進(jìn)行運行,或者使用工具idea直接啟動,便于開發(fā)調(diào)試,本文給大家分享SpringBoot項目打包成war包并部署在tomcat上運行的操作步驟,感興趣的朋友一起看看吧2024-03-03
Java中使用BeanMap將對象轉(zhuǎn)為Map詳解
這篇文章主要介紹了Java中使用BeanMap將對象轉(zhuǎn)為Map詳解,BeanMap?是?Apache?Commons?BeanUtils?庫中的一個類,BeanMap?可以將?Java?對象的屬性作為鍵,屬性值作為對應(yīng)的值,存儲在一個?Map?中,它提供了一種將?Java?對象轉(zhuǎn)換為?Map?的方式,需要的朋友可以參考下2024-01-01
解決Eclipse中java文件的圖標(biāo)變成空心J的問題
這篇文章主要介紹了解決Eclipse中java文件的圖標(biāo)變成空心J的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
Spring框架基于AOP實現(xiàn)簡單日志管理步驟解析
這篇文章主要介紹了Spring框架基于AOP實現(xiàn)簡單日志管理步驟解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06
Springboot使用Rabbitmq的延時隊列+死信隊列實現(xiàn)消息延期消費
本文介紹了RabbitMQ的延時隊列和死信隊列,解釋了它們的工作原理及其應(yīng)用場景,延時隊列允許消息在設(shè)定的時間后被消費,結(jié)合實際案例,展示了如何實現(xiàn)和使用延時隊列和死信隊列,感興趣的朋友一起看看吧2025-01-01
使用jquery 的ajax 與 Java servlet的交互代碼實例
這篇文章主要介紹了使用jquery 的ajax 與 Java servlet的交互代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09
Java源碼解析HashMap的tableSizeFor函數(shù)
今天小編就為大家分享一篇關(guān)于Java源碼解析HashMap的tableSizeFor函數(shù),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-01-01

