aqs速讀 頂 原

說起aqs很多人都感覺很頭疼,下文就從幾個角度瞭解,讓你快速瞭解aqs。

預熱知識

aqs獲取鎖等主要用的cas以及locksupport。對鎖的控制是一個int類型的狀態state。例如獲取鎖就是通過cas把state從0變成1。

獨佔鎖

圖片描述

3個線程都去修改狀態,cas只有一個修改成功。剩下的都會失敗,並且開始進入一個隊列中。 圖片描述

線程2,加入隊列後,就會判斷自己是否可以去搶鎖(只有pre是head的纔可以搶鎖),如果搶不到,就用locksupport掛起。線程3也一樣。此時線程2和3都是掛起狀態。 圖片描述

當1釋放鎖。釋放的過程就是修改狀態,例如把1改成0。然後利用locksupport喚醒head的下一個節點。此時2被喚醒再次重複搶鎖,失敗掛起的流程。

公平鎖

經過上面的流程,大家也發現了一個問題,就是修改狀態和喚醒節點,不是一個原子操作,如果我剛釋放,正好就被一個新的進程修改成功,線程2嘗試獲取鎖是失敗的。這就是非公平鎖。公平鎖,在改狀態之前,會先判斷一下,等待的隊列的頭指針和尾指針是否相同(隊列是否爲空)。這樣就保證了隊列裏的線程有比較高的優先級拿到鎖。

重入鎖

重入鎖就是當前線程已經獲取鎖了,再次獲取鎖的時候就可以不用拍在隊列裏。這個邏輯也是在獲取鎖的地方判定的,獲取鎖的時候,判定一下正在拿到鎖的線程是否是當前線程。如果是就在狀態上+1。釋放鎖的時候也是+1。直到減到0,纔去喚醒阻塞的線程。

共享鎖

共享鎖其實是多個線程可以同時拿到鎖的。流程狀態與獨佔鎖沒有區別,在阻塞隊列裏獲取鎖的時候多了一些操作。釋放資源的時候還是喚醒head的下一個節點,那麼在共享鎖裏,就存在一種情況,多個線程同時釋放資源喚醒的都是head的next,如果此時只有一個節點獲取鎖的話,那麼資源就浪費了。所以,共享鎖在之前的邏輯上多了一步,就是獲取鎖資源以後,會判斷是否還有鎖資源。如果有,就再走一次釋放鎖資源的過程。讓後續的節點繼續獲取資源。

小結

對於aqs。主流程就是,嘗試獲取鎖資源,失敗入隊列,再次獲取鎖,失敗後,等待被喚醒,喚醒後繼續獲取鎖資源,然後根據鎖的類型再處理情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章