AQS框架 談談對AQS框架的理解

2021-10-24 01:15:36 字數 1839 閱讀 5207

aqs是乙個框架,基於它我們可以實現鎖和同步器,j.u.c.包中和很多鎖和同步器都是基於aqs實現的。

使用aqs的方式通常不是讓鎖或同步器直接繼承aqs類,而是將aqs的子類作為鎖或同步器類的乙個輔助內部類,鎖或同步器的方法呼叫aqs子類物件的方法完成同步操作。

(來自網路)

aqs中最重要的乙個字段就是同步狀態字段state,鎖和同步器的實現都是圍繞著這個欄位的修改展開的,aqs中也暴露出了一些方法供我們重寫以操作這個字段,例如tryacquire, tryrelease, tryacquireshared, tryreleaseshared,這四個方法底層又是呼叫aqs提供的getstate, setstate, compareandswapstate來修改同步狀態。

aqs可以實現各種不同的鎖和同步器的原因之一就是,不同的鎖或同步器按照自己的需要可以對同步狀態的含義有不同的定義,並重寫對應的tryacquire, tryrelease或tryacquireshared, tryreleaseshared等方法來操作同步狀態。

對於修改同步狀態失敗的執行緒,以及呼叫await而阻塞的執行緒,aqs替我們提供了這些執行緒的管理機制,包括執行緒的排隊、阻塞和喚醒等等。這些執行緒的管理機制對於鎖和同步器的編寫者來說透明的,他們也沒有必要修改這些執行緒管理相關的方法,因此這些方法在aqs類中被宣告為final的,這裡用到了模板方法設計模式。

aqs內部的執行緒管理是基於佇列的,aqs內部有兩個佇列可以用來管理執行緒,分別是同步佇列條件佇列

同步佇列是基於clh佇列改進得到的,它是乙個基於雙鏈表的佇列,獲取同步狀態失敗而需要阻塞的執行緒會被放入同步佇列,並在合適的時機被喚醒。同步佇列中的節點有獨佔模式共享模式,對於獨佔模式,同一時刻只能有乙個執行緒持有鎖;對於共享模式,同一時刻可以有多個執行緒持有鎖,針對這兩個模式的節點,aqs分別提供了不同的api。

條件佇列是乙個基於單鏈表的佇列,它主要是為了實現await和signal方法,這兩個方法類似object類中的wait和signal。當執行緒呼叫await方法時,它會被封裝為node節點放入條件佇列末尾,釋放同步狀態然後阻塞;當await阻塞的執行緒被喚醒或中斷時,會導致轉移到同步佇列,然後恢復同步狀態。

此外,aqs暴露出來了訪問同步佇列和條件佇列狀態的方法,如下圖所示:

通過這些方法我們可以訪問同步佇列的長度、獲取同步佇列中所有獨佔模式執行緒/共享模式執行緒,可以查詢當前執行緒對應的節點在同步佇列中是否有前驅 (hasqueuedprocessors())等等。

借助這些方法,我們可以實現一些額外的特性。例如借助hasqueuedprocessors()方法我們可以實現公平性reentrantlock中的公平鎖就用到了這點,每次嘗試修改同步狀態前,必須先呼叫該方法確保同步佇列中沒有在該執行緒之前就開始等待的執行緒之後,才能夠修改同步狀態;否則,該節點需要排隊等待。

AQS框架基本流程

我們先來看一下這個併發框架的原理,在之後的文章中我們將乙個乙個的分析那些有用的實現。public final void acquire int arg 這個方法是獲取到資源的入口,首先他會嘗試來獲取arg個資源,如果沒有獲取成功,就會呼叫後面的方法將這次請求放到乙個同步佇列裡面,如果都失敗了,就會呼...

AQS框架實現類學習

author jinxindong 2016年11月1日 上午9 33 46 version v1.0 public class countdownlatchdemo static class worker extends thread public void run catch interrupt...

併發程式設計核心框架AQS之獨佔鎖原理詳解

如何設計符合冪等性的高質量restful api 理解restful的冪等性,並且設計符合冪等規範的高質量restful api。http冪等方法,是指無論呼叫多少次都不會有不同結果的 http 方法。不管你呼叫一次,還是呼叫一百次,一千次,結果都是相同的。還是以之前的博文的例子為例。get tic...