天天看點

java多線程:并發包中ReentrantLock鎖的公平鎖原理

一:鎖的原理結構

(1)鎖對象内部維護了一個同步管理器的對象AbstractQueuedSynchronizer,AbstractOwnableSynchronizer

(2)該對象其實是一個抽象類,具體的鎖的管理器繼承該抽象類

(3)該抽象類的關鍵屬性有:---->Thread exclusiveOwnerThread(擷取鎖的線程對象)

----> Node head(首節點,正在擁有目前鎖的線程構造的Node對象)

---->Node tail(尾巴節點,等待擷取鎖的線程構造的雙向連結清單結構的隊列的最後一個節點)

---->int state(目前該鎖被線程争搶的狀态,如果state=0,表示無線程争搶該鎖,如果state>0則表示已經有線程擁有該鎖)

二:鎖中的Node隊列的結構

(1)所有的線程在執行到擷取鎖的代碼的部分,都會調用同步管理器的lock()方法,如果有線程擷取鎖,則将該線程構造成node對象,添加到隊列尾部,并調用系統指令阻塞目前線程。也就是代碼執行到這,目前線程就不再執行。

(2)擁有鎖的線程,在釋放鎖的時候,會喚醒自己的後繼節點的線程,讓其争搶鎖。

(3)Node的内部結構屬性

--->int waitStatus(目前node的線程在争搶鎖過程的狀态辨別)

--->Node prev(目前node的上一個node的引用,前驅節點)

--->Node next(目前node的下一個INITALnode的引用,後繼節點)

--->Thread thread(目前node所代表的線程的線程對象)

--->Node nextWaiter(下一個等待着的node)

(4)node等待狀态的的含義

CANCELLED =  1:由于同步隊列中等待線程等待逾時或被中斷,需要從同步隊列中取消等待,節點進入該狀态不會再變化

SIGNAL    = -1:後繼節點線程處于等待狀态,而目前節點的線程如果釋放了同步狀态或者被取消,将會通知後繼節點,使後繼節點得以運作。

CONDITION = -2:在等待隊列中,節點線程等待在Condition上,當其他線程對Condition調用了signal()方法後,該節點将會從等待隊列中轉移到同步隊列中。加入到對同步狀态的擷取中。

PROPAGATE = -3:表示下一次共享式同步狀态擷取将會無條件被傳播下去。

INITIAL=0:初始化狀态

三:公平鎖和非公平鎖的差別

(1)公平鎖的鎖擷取,嚴格按照等待順序進行鎖擷取,在擷取鎖的時候有一個判斷hasQueuedPredeccssors(),同步隊列中是否有前驅節點在等待擷取鎖,如果有,則放棄擷取鎖,而是添加到隊尾,排隊擷取鎖

(2)非公平鎖,是擷取鎖的順序是随機的,甚至,有的線程可能會一直無法擷取鎖,出現線程饑餓情況。

(3)公平鎖的性能往往沒有非公平鎖的性能高,因為它需要排隊,則需要進行程式狀态的切換,要比非公平鎖的切換次數多。

四:鎖的擷取和釋放的過程圖

java多線程:并發包中ReentrantLock鎖的公平鎖原理