什么是可重入鎖(Reentrant Lock)?
可重入鎖(又名遞歸鎖)是一種特殊類型的鎖,它允許同一個線程在獲取鎖后再次進入該鎖保護的代碼塊或方法,而不需要重新獲取鎖。
說白了,可重入鎖的特點就是同一個線程可以多次獲取同一個鎖,而不會因為之前已經獲取過鎖而阻塞。
可重入鎖的一個優(yōu)點是可以一定程度避免死鎖。
舉例可重入鎖
在Java中,ReentrantLock
和synchronized
都是可重入鎖。
synchronized
public class ReentrantLockDemo {
public synchronized void outerMethod() {
System.out.println("進入外層方法");
innerMethod();
System.out.println("退出外層方法");
}
public synchronized void innerMethod() {
System.out.println("進入內層方法");
// Do some work
System.out.println("退出內層方法");
}
public static void main(String[] args) {
ReentrantLockDemo demo = new ReentrantLockDemo();
demo.outerMethod();
}
}
在
outerMethod外層方法
中獲取鎖的線程能夠在innerMethod內層方法
中重新獲取同一個鎖,而不需要阻塞。
運行結果如下:
進入外層方法
進入內層方法
退出內層方法
退出外層方法
ReentrantLock
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo {
private ReentrantLock lock = new ReentrantLock();
public void outerMethod() {
lock.lock(); // 獲取鎖
try {
System.out.println("進入外層方法");
innerMethod();
System.out.println("退出外層方法");
} finally {
lock.unlock(); // 釋放鎖
}
}
public void innerMethod() {
lock.lock(); // 再次獲取鎖
try {
System.out.println("進入內層方法");
// 執(zhí)行一些操作
System.out.println("退出內層方法");
} finally {
lock.unlock(); // 釋放鎖
}
}
public static void main(String[] args) {
ReentrantLockDemo demo = new ReentrantLockDemo();
demo.outerMethod();
}
}
Synchronized可重入的實現原理
事實上,每個鎖對象擁有一個鎖計數器和一個指向持有該鎖的線程的指針。
當執(zhí)行 monitorenter
指令時,如果目標鎖對象的計數器為零,那么說明它沒有被其他線程所持有,Java 虛擬機會將該鎖對象的持有線程設置為當前線程,并且將其計數器加 1。
在目標鎖對象的計數器不為零的情況下,如果鎖對象的持有線程是當前線程,那么 Java 虛擬機可以將其計數器加 1,這是因為鎖是可重入的,當前線程可以多次獲取同一個鎖。否則,如果鎖對象的持有線程不是當前線程,那么當前線程需要等待,直至持有線程釋放該鎖。
當執(zhí)行 monitorexit
指令時,Java 虛擬機則需將鎖對象的計數器減 1。如果計數器減到零,那么鎖就被釋放了。文章來源:http://www.zghlxwxcb.cn/news/detail-857005.html
monitorenter
和monitorexit
指令是 Java 字節(jié)碼中的指令,它們是由 Java 編譯器生成的。文章來源地址http://www.zghlxwxcb.cn/news/detail-857005.html
到了這里,關于【Java | 多線程】可重入鎖的概念以及示例的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!