Chapter 5 Java中的鎖(一)

5.1 LOCK接口

鎖是用于控制多個線程訪問共享資源的方式。一般來說,一個鎖能夠防止多個線程同一時間訪問一個共享資源(但是有些鎖可以允許多個線程并發(fā)的訪問共享資源,比如讀寫鎖)。

Lock接口提供了與synchronized關(guān)鍵字類似的功能,只是在使用時需要顯示的獲取和釋放鎖。雖然它缺少了(synchronized塊或方法所提供的)隱式獲取和釋放鎖的便捷性,但是卻擁有了鎖獲取與釋放的可操作性,可中斷的獲取鎖以及超時獲取鎖等synchronized關(guān)鍵字所不具備的同步特性。

Lock接口的使用示例:

Lock lock = new ReentrantLock();

lock.lock();

try{

}finally{

? ? ? lock.unlock();

}

Lock 接口所提供的的synchronized關(guān)鍵字不具備的功能:

(1)嘗試非阻塞的獲取鎖。

(2)能被中斷地獲取鎖:與synchronized不同,當(dāng)獲取到鎖的線程被中斷時,中斷異常將被拋出,同時鎖被釋放。

(3)超時獲取鎖:如果在規(guī)定時間內(nèi)無法獲得鎖,則及時返回。


5.2 隊列同步器

隊列同步器AbstractQueuedSynchronizer,使用來構(gòu)建鎖或者其他同步組件的基礎(chǔ)框架。

同步器主要通過操作3個方法來對同步狀態(tài)進(jìn)行更改,getState(),setState(int newState),compareAndSet(int expected,intupdate)。這些方法能都保證狀態(tài)的改變是安全的。

同步器是實現(xiàn)鎖(或任何其他同步組件)的關(guān)鍵,通常在鎖的實現(xiàn)中聚合同步器,利用同步器來實現(xiàn)鎖的語義。同步器簡化了鎖的實現(xiàn),屏蔽了同步狀態(tài)管理,線程的排隊,等待與喚醒等底層操作。

5.2.1 隊列同步器的接口與示例

(1)隊列同步器是基于模板方法模式的,也就是說,使用者需要繼承同步器并重寫指定的方法。

同步器可重寫的方法如下

(1)protected boolean tryAcquire(int arg):獨(dú)占式的獲取同步狀態(tài),實現(xiàn)該方法需要判斷同步狀態(tài)是否符合預(yù)期,然后進(jìn)行CAS設(shè)置同步狀態(tài)。

(2)protected boolean tryRelease(int arg):獨(dú)占式釋放同步狀態(tài),等待獲取同步狀態(tài)的線程將有機(jī)會獲取同步狀態(tài)。

(3)protected boolean tryAcquireShared(int arg):共享式獲取同步狀態(tài),返回大于0的值,表示獲取成功,反之,獲取失敗。

(4)protected boolean tryReleaseShared(int arg):共享式釋放同步狀態(tài)

(5)protected boolean isHeldExclusively():是否被當(dāng)前線程獨(dú)占

同步器提供的模板方法:

(1)void acquire(int arg):獨(dú)占式獲取同步狀態(tài),如果當(dāng)前線程獲取同步狀態(tài)成功,則由該方法返回,否則,線程進(jìn)入同步隊列等待,該方法會調(diào)用重寫的tryAcquire方法。

(2)void acquireInterruptibly(int arg):與acquire(int arg)相同,但是該方法能夠響應(yīng)中斷,如果當(dāng)前線程被中斷,則該方法會拋出InterruptedException并返回。

(3)boolean tryAcquireNanos(int arg,long nanos):在acquireInterruptibly(int arg)的基礎(chǔ)上增加了超時限制,如果當(dāng)前線程在超時時間內(nèi)沒有獲取到同步狀態(tài),那么將返回false,否則返回true。

(4)boolean release(int arg):獨(dú)占式釋放同步狀態(tài),該方法會在釋放同步狀態(tài)之后,將同步狀態(tài)中第一個節(jié)點(diǎn)包含的線程喚醒。

(5)Collection<Thread> getQueuedThreads():獲取等待在同步隊列上的線程集合

同步器提供的方法主要分為3類:獨(dú)占式獲取和釋放同步狀態(tài)共享式獲取和釋放同步狀態(tài),查詢同步隊列中的等待線程情況。


5.3 重入鎖

重入鎖(ReentrantLock),就是支持重進(jìn)入的鎖,它表示該鎖能夠支持一個線程對資源的重復(fù)加鎖。除此之外,該鎖還支持獲取鎖時的公平和非公平性選擇。

synchronized關(guān)鍵字隱式的支持重進(jìn)入。

(1)公平鎖:如果在絕對時間上,先對鎖進(jìn)行請求的鎖先被滿足,那么這個鎖就是公平的,反之,就是不公平的。公平的獲取鎖,也就是等待時間最長的線程最優(yōu)先獲得鎖,也可以說鎖的獲取是順序的。

(2)事實上,公平鎖往往沒有非公平鎖的效率高(公平鎖造成大量的線程切換開銷),但是,公平鎖能夠減少“饑餓”發(fā)生的概率。

(3)非公平鎖雖然可能造成線程饑餓,但極少的線程切換,保證了其更大的吞吐量。

ReentrantLock的實現(xiàn):

(1)nonfairTryAcquire:判斷當(dāng)前線程是否為獲取鎖的線程,如果是,則將同步狀態(tài)的值增加并返回true。

(2)tryRelease:如果該鎖被獲取了n次,那么前(n-1)次tryRelease方法必須返回flase,而只有同步狀態(tài)最終被減為0的時候才能返回true。

(3)公平鎖的tryAcquire與nonfairTryAcquire唯一的區(qū)別就是,判斷條件多了hasQueuedPredecessors()方法,即加入了同步隊列當(dāng)前節(jié)點(diǎn)是否有前驅(qū)節(jié)點(diǎn)的判斷,如果有的話,tryAcquire會返回false。

nonfairTryAcquire


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

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

  • 5.4 讀寫鎖 之前提到的鎖如Mutex和ReentrantLock都是排它鎖,這些鎖同一時刻都只允許一個線程進(jìn)行...
    伊凡的一天閱讀 610評論 0 1
  • Java并發(fā)編程的藝術(shù)筆記 1.并發(fā)編程的挑戰(zhàn)[http://www.itdecent.cn/p/8c9d063...
    一個秋閱讀 866評論 0 0
  • 1.Lock接口 一般來說,一個鎖能夠防止多個線程同時訪問共享資源(但有些鎖可以允許多個線程并發(fā)的訪問共享資源,比...
    加夕閱讀 539評論 0 1
  • 主要內(nèi)容有:Lock接口隊列同步器重入鎖讀寫鎖LockSupport工具Condition接口 1.Lock接口 ...
    htkeepmoving閱讀 322評論 0 1
  • 1.Lock 接口 ??鎖是用來控制多個線程訪問共享資源的方式,一般來說, 一個鎖能夠防止多個線程同時訪問共享資源...
    ShayHe閱讀 426評論 0 0

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