鍍金池/ 教程/ Java/ 可重入內(nèi)置鎖
并發(fā)新特性—信號(hào)量 Semaphore
線程間協(xié)作:wait、notify、notifyAll
notify 通知的遺漏
notifyAll 造成的早期通知問(wèn)題
多線程的實(shí)現(xiàn)方法
深入 Java 內(nèi)存模型(1)
多線程環(huán)境下安全使用集合 API
并發(fā)新特性—Lock 鎖與條件變量
生產(chǎn)者—消費(fèi)者模型
深入 Java 內(nèi)存模型(2)
線程中斷
Volatile 關(guān)鍵字(上)
并發(fā)新特性—阻塞隊(duì)列與阻塞棧
可重入內(nèi)置鎖
守護(hù)線程與線程阻塞
并發(fā)新特性—障礙器 CyclicBarrier
Volatile 關(guān)鍵字(下)
synchronized 關(guān)鍵字
synchronized 的另個(gè)一重要作用:內(nèi)存可見(jiàn)性
并發(fā)新特性—Executor 框架與線程池
并發(fā)性與多線程介紹
死鎖
實(shí)現(xiàn)內(nèi)存可見(jiàn)性的兩種方法比較:synchronized 和 Volatile
線程掛起、恢復(fù)與終止

可重入內(nèi)置鎖

每個(gè) Java 對(duì)象都可以用做一個(gè)實(shí)現(xiàn)同步的鎖,這些鎖被稱為內(nèi)置鎖或監(jiān)視器鎖。線程在進(jìn)入同步代碼塊之前會(huì)自動(dòng)獲取鎖,并且在退出同步代碼塊時(shí)會(huì)自動(dòng)釋放鎖。獲得內(nèi)置鎖的唯一途徑就是進(jìn)入由這個(gè)鎖保護(hù)的同步代碼塊或方法。

當(dāng)某個(gè)線程請(qǐng)求一個(gè)由其他線程持有的鎖時(shí),發(fā)出請(qǐng)求的線程就會(huì)阻塞。然而,由于內(nèi)置鎖是可重入的,因此如果摸個(gè)線程試圖獲得一個(gè)已經(jīng)由它自己持有的鎖,那么這個(gè)請(qǐng)求就會(huì)成功。“重入”意味著獲取鎖的操作的粒度是“線程”,而不是調(diào)用。重入的一種實(shí)現(xiàn)方法是,為每個(gè)鎖關(guān)聯(lián)一個(gè)獲取計(jì)數(shù)值和一個(gè)所有者線程。當(dāng)計(jì)數(shù)值為 0 時(shí),這個(gè)鎖就被認(rèn)為是沒(méi)有被任何線程所持有,當(dāng)線程請(qǐng)求一個(gè)未被持有的鎖時(shí),JVM 將記下鎖的持有者,并且將獲取計(jì)數(shù)值置為 1,如果同一個(gè)線程再次獲取這個(gè)鎖,計(jì)數(shù)值將遞增,而當(dāng)線程退出同步代碼塊時(shí),計(jì)數(shù)器會(huì)相應(yīng)地遞減。當(dāng)計(jì)數(shù)值為 0 時(shí),這個(gè)鎖將被釋放。

重入進(jìn)一步提升了加鎖行為的封裝性,因此簡(jiǎn)化了面向?qū)ο蟛l(fā)代碼的開(kāi)發(fā)。分析如下程序:

public class Father  
{  
    public synchronized void doSomething(){  
        ......  
    }  
}  

public class Child extends Father  
{  
    public synchronized void doSomething(){  
        ......  
        super.doSomething();  
    }  
} 

子類覆寫(xiě)了父類的同步方法,然后調(diào)用父類中的方法,此時(shí)如果沒(méi)有可重入的鎖,那么這段代碼件產(chǎn)生死鎖。

由于 Fither 和 Child 中的 doSomething 方法都是 synchronized 方法,因此每個(gè) doSomething 方法在執(zhí)行前都會(huì)獲取 Child 對(duì)象實(shí)例上的鎖。如果內(nèi)置鎖不是可重入的,那么在調(diào)用 super.doSomething 時(shí)將無(wú)法獲得該 Child 對(duì)象上的互斥鎖,因?yàn)檫@個(gè)鎖已經(jīng)被持有,從而線程會(huì)永遠(yuǎn)阻塞下去,一直在等待一個(gè)永遠(yuǎn)也無(wú)法獲取的鎖。重入則避免了這種死鎖情況的發(fā)生。

同一個(gè)線程在調(diào)用本類中其他 synchronized 方法/塊或父類中的 synchronized 方法/塊時(shí),都不會(huì)阻礙該線程地執(zhí)行,因?yàn)榛コ怄i時(shí)可重入的。