JDK并發(fā)包之重入鎖

鎖:對共享數(shù)據(jù)加鎖使其變?yōu)榕R界區(qū)。(排它鎖)與共享鎖

鎖有內(nèi)部鎖(synchronized關(guān)鍵字修飾的)與顯式鎖(Java.concurrent.locks.Lock接口)。

顯式鎖與內(nèi)部鎖的比較

各適用環(huán)境不同,而非相互代替,內(nèi)部鎖申請或者釋放一個鎖必須在塊或者同一方法中,靈活性更差,但方便,不會導(dǎo)致鎖泄露;而顯式鎖可以跨方法釋放鎖,靈活性更高,但容易鎖泄露,操作不方便,繁瑣。同時顯示鎖支持狠多內(nèi)部鎖不支持的特性。

顯式鎖之重入鎖:

重入鎖存在于Java.util.concurrent.locks.ReentrantLock類。

例如:

之所以稱為重入鎖,是因為可以同一線程重復(fù)上鎖,即兩次上鎖,兩次釋放鎖。

中斷響應(yīng):指兩個線程出現(xiàn)死鎖可以控制一方放棄申請鎖,并釋放已獲得鎖

首先營造一個死鎖:


對于這種情況,我們能想到的辦法為中斷其中一個線程,即:


但這種方式需要在run方法中加isinterrupted作為標(biāo)志位,只有為TRUE,才可中斷,所以:


不需標(biāo)志位判斷

兩種中斷比較:


lock()加鎖
lockInterruptibly()加鎖

鎖申請限時等待:

除了外部通知某個線程中斷來處理死鎖外,避免死鎖還有另外方法:tryLock()


輸出結(jié)果圖p75

所以,對于上面的死鎖問題,我們可以這樣解決:


else同理

這樣,經(jīng)過幾秒后,線程t1與t2都會得到鎖資源并順利執(zhí)行完畢。

公平鎖:

不會產(chǎn)生饑餓現(xiàn)象,synchronized不允許公平鎖

說明:ReentrantLock(true)表示公平鎖,其看來優(yōu)美,但要實現(xiàn)公平鎖,需要維護一個有序隊列,因此公平鎖實現(xiàn)成本高,性能低下,因此,一般情況下,鎖是非公平的。如果沒有特殊要求,也不推薦使用公平鎖。

對于系統(tǒng)調(diào)度而言,一個線程更傾向于再此獲得已經(jīng)持有的鎖,這種分配方式是高效的。

使用公平鎖的結(jié)果就是,以時間片為單位,交替獲得,而不公平鎖大部分都是重復(fù)輸出。

總結(jié):重入鎖的幾個重要方法:

ReentrantLock()構(gòu)造方法:實現(xiàn)公平非公平鎖

lock():獲得鎖

lockInterruptibly():獲得鎖,但優(yōu)先響應(yīng)中斷

tryLock():獲得鎖(資源),若鎖被占用,返回false

tryLock(long time,TimeUnit unit):給定時間內(nèi)獲得鎖

unlock():釋放鎖,千萬不要忘記。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容