鎖:對共享數(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,才可中斷,所以:

兩種中斷比較:


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


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

這樣,經(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():釋放鎖,千萬不要忘記。