天天看點

java基礎總結(八十八)--synchronized也是可重入的

原文連結、

可重入鎖,從字面來了解,就是可以重複進入的鎖。

可重入鎖,也叫做遞歸鎖,指的是同一線程外層函數獲得鎖之後,内層遞歸函數仍然有擷取該鎖的代碼,但不受影響。

在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

也沒有發生死鎖,證明其是可重入的。

總結

以上就是這篇文章的全部内容了,希望本文的内容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支援。如果你想了解更多相關内容請檢視下面相關連結