可重入鎖,從字面來理解,就是可以重復進入的鎖。
可重入鎖,也叫做遞歸鎖,指的是同一線程外層函數獲得鎖之后,內層遞歸函數仍然有獲取該鎖的代碼,但不受影響。
在java環境下reentrantlock
和synchronized
都是可重入鎖。
synchronized
是一個可重入鎖。在一個類中,如果synchronized方法1調用了synchronized方法2,方法2是可以正常執行的,這說明synchronized是可重入鎖。否則,在執行方法2想獲取鎖的時候,該鎖已經在執行方法1時獲取了,那么方法2將永遠得不到執行。
可重入鎖在什么場景使用呢?
可重入鎖主要用在線程需要多次進入臨界區代碼時,需要使用可重入鎖。具體的例子,比如上文中提到的一個synchronized方法需要調用另一個synchronized方法時。
可重入鎖的實現原理是怎么樣的?
加鎖時,需要判斷鎖是否已經被獲取。如果已經被獲取,則判斷獲取鎖的線程是否是當前線程。如果是當前線程,則給獲取次數加1。如果不是當前線程,則需要等待。
釋放鎖時,需要給鎖的獲取次數減1,然后判斷,次數是否為0了。如果次數為0了,則需要調用鎖的喚醒方法,讓鎖上阻塞的其他線程得到執行的機會。
下面是一個用synchronized實現的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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(); } } } |
整個過程沒有發生死鎖的情況,截取一部分輸出結果如下:
thread-8492
thread-8492
thread-8494
thread-8494
thread-8495
thread-8495
thread-8493
thread-8493
set()
和get()
同時輸出了線程名稱,表明即使遞歸使用synchronized
也沒有發生死鎖,證明其是可重入的。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。如果你想了解更多相關內容請查看下面相關鏈接
原文鏈接:https://blog.csdn.net/li_canhui/article/details/84556412