併發(一):理解可重入鎖
阿新 • • 發佈:2019-01-23
在JAVA中,內建鎖都是可重入的,也就是說,如果某個執行緒試圖獲取一個已經由它自己持有的鎖時,那麼這個請求會立刻成功,並且會將這個鎖的計數值加1,而當執行緒退出同步程式碼塊時,計數器將會遞減,當計數值等於0時,鎖釋放。
看例子,一目瞭然:
new Thread() {
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run() {
// 第一次獲得鎖
synchronized(this) {
while (true) {
// 第二次獲得同樣的鎖
synchronized(this) {
System.out.println("ReteenLock!");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
如果沒有可重入鎖的支援,在第二次企圖獲得鎖時將會進入死鎖狀態。在實際的程式碼中,我們可能不會這麼寫程式碼,但是可重入鎖依舊隨處可見,如下:
public class PartBuilder {
public synchronized void buildPart_1() {
}
public synchronized void buildPart_2() {
}
/**
* 很明顯的可重入鎖用法
*/
public synchronized void buildPart() {
this .buildPart_1();
this.buildPart_2();
}
}
在上面的例子中,進入buildPart()方法時已經獲取了物件鎖,在呼叫buildPart_1()時又再次獲取物件鎖,此時物件的鎖計數值已經達到2了。
結論
JAVA的可重入鎖提升了加鎖行為的封裝性,大大簡化了面向物件併發程式碼開發的難度。