AQS詳解:
AQS原理
AQS:AbstractQuenedSynchronizer抽象的隊列式同步器廓潜。是除了java自帶的synchronized關鍵字之外的鎖機制。
AQS的全稱為(AbstractQueuedSynchronizer)悼院,這個類在java.util.concurrent.locks包
AQS的核心思想是叙甸,如果被請求的共享資源空閑,則將當前請求資源的線程設置為有效的工作線程哪痰,并將共享資源設置為鎖定狀態(tài),如果被請求的共享資源被占用抑诸,那么就需要一套線程阻塞等待以及被喚醒時鎖分配的機制,這個機制AQS是用CLH隊列鎖實現(xiàn)的,即將暫時獲取不到鎖的線程加入到隊列中辛块。
CLH(Craig,Landin,and Hagersten)隊列是一個虛擬的雙向隊列,虛擬的雙向隊列即不存在隊列實例娇澎,僅存在節(jié)點之間的關聯(lián)關系伪很。
AQS是將每一條請求共享資源的線程封裝成一個CLH鎖隊列的一個結(jié)點(Node)猫十,來實現(xiàn)鎖的分配应又。
用大白話來說尤筐,AQS就是基于CLH隊列,用volatile修飾共享變量state,線程通過CAS去改變狀態(tài)符拦惋,成功則獲取鎖成功吞彤,失敗則進入等待隊列饰恕,等待被喚醒。
注意:AQS是自旋鎖:在等待喚醒的時候,經(jīng)常會使用自旋(while(!cas()))的方式,不停地嘗試獲取鎖,直到被其他線程獲取成功
實現(xiàn)了AQS的鎖有:自旋鎖、互斥鎖撩鹿、讀鎖寫鎖稚机、條件產(chǎn)量、信號量纬乍、柵欄都是AQS的衍生物
AQS 定義了兩種資源共享方式:
1.Exclusive:獨占墓贿,只有一個線程能執(zhí)行,如ReentrantLock
2.Share:共享,多個線程可以同時執(zhí)行,如Semaphore击吱、CountDownLatch、ReadWriteLock憨奸,CyclicBarrier
AQS底層使用了模板方法模式
同步器的設計是基于模板方法模式的党瓮,如果需要自定義同步器一般的方式是這樣(模板方法模式很經(jīng)典的一個應用):
使用者繼承AbstractQueuedSynchronizer并重寫指定的方法在跳。(這些重寫方法很簡單割坠,無非是對于共享資源state的獲取和釋放)
將AQS組合在自定義同步組件的實現(xiàn)中单旁,并調(diào)用其模板方法愉豺,而這些模板方法會調(diào)用使用者重寫的方法。
這和我們以往通過實現(xiàn)接口的方式有很大區(qū)別括袒,這是模板方法模式很經(jīng)典的一個運用。