併發程式設計AQS(網課整理)(未完)

2021-10-05 14:37:04 字數 1291 閱讀 3563

通過jcp的jsr166規範,jdk1.5開始引入了j.u.c包,這個包提供了一系列支援併發的元件。這些元件是一系列的同步器,這些同步器主要維護著以下幾個功能:內部同步狀態的管理(例如表示乙個鎖的狀態是獲取還是釋放),同步狀態的更新和檢查操作,且至少有乙個方法會導致呼叫執行緒在同步狀態被獲取時阻塞,以及在其他執行緒改變這個同步狀態時解除執行緒的阻塞。上述的這些的實際例子包括:互斥排它鎖的不同形式、讀寫鎖、訊號量、屏障、future、事件指示器以及傳送佇列等。可以看下這裡圖便能理解 j.u.c包的元件構成。

幾乎任一同步器都可以用來實現其他形式的同步器。例如,可以用可重入鎖實現訊號量或者用訊號 量實現可重入鎖。但是,這樣做帶來的複雜性、開銷及不靈活使j.u.c最多只能是乙個二流工程,且缺乏吸引力。如果任何這樣的構造方式不能在本質上比其他形式更簡潔,那麼開發者就不應該隨意地選擇其中的某個來構建另乙個同步器。因此,jsr166基於aqs類建立了乙個小框架,這個框架為構造同步器提供一種通用的機制,並且被j.u.c包中大部分類使用,同時很多使用者也可以用它來定義自己的同步器。這個就是j.u.c的作者doug lea大神的初衷,通過提供aqs這個基礎元件來構建j.u.c的各種工具類,至此就可以理解aqs的產生背景了。

同步器的核心方法是acquire和release操作,其背後的思想也比較簡潔明確。

從這兩個操作中的思想中我們可以提取出三大關鍵操作:同步器的狀態變更、執行緒阻塞和釋放、插入和移出佇列。所以為了實現這兩個操作,需要協調三大關鍵操作引申出來的三個基本元件:

由這三個基本元件,我們來看j.u.c是怎麼設計的。

2.1.1 同步狀態

aqs類使用單個int(32位)來儲存同步狀態,並暴露出getstate、setstate以及compareandset 操作來讀取和更新這個同步狀態。其中屬性state被宣告為volatile,並且通過使用cas指令來實現 compareandsetstate,使得當且僅當同步狀態擁有乙個一致的期望值的時候,才會被原子地設定成新 值,這樣就達到了同步狀態的原子性管理,確保了同步狀態的原子性、可見性和有序性。

基於aqs的具體實現類(如鎖、訊號量等)必須根據暴露出的狀態相關的方法定義tryacquire和 tryrelease方法,以控制acquire和release操作。當同步狀態滿足時,tryacquire方法必須返回true, 而當新的同步狀態允許後續acquire時,tryrelease方法也必須返回true。這些方法都接受乙個int型別的引數用於傳遞想要的狀態。

2.1.2 阻塞

java併發程式設計的藝術(六) AQS

aqs是佇列同步器 abstractqueuesynchronizer 是用來構建鎖和完成其他同步元件的基本框架,再lock裡面,很多的方法都將用到aqs以獲取同步狀態,實現鎖的語義,而不是依靠傳統的synchronized中的物件進行鎖獲取與釋放。aqs的核心思想是基於volatile int s...

併發程式設計之AQS的同步原理

aqs abstractqueuedsynchronizer 抽象佇列同步器。aqs的同步狀態 aqs使用乙個int成員變數來表示同步狀態,通過內建的fifo佇列來完成獲取資源執行緒的排隊工作。aqs使用cas對該同步狀態進行原子操作實現對其值的修改。private volatile int sta...

併發程式設計學習整理

1.hashmap採用位運算定位陣列的下標,因為位運算效率高於模運算 2.hash的資料容量不是2次冪得話,可能造成hash不均勻,乙個位置可能永遠放不到 1.jdk7版本之前的concurrenthasmap採用seagment分段鎖的思想,進行兩次hash找到資料存放的位置,但是jdk8之後放棄...