其實一開始是想接著寫java鎖的,不過后面發(fā)現(xiàn)內(nèi)置鎖和其他同步器基本都離不開AQS丰辣。既然AQS繞不過去撒强,那只好就開始探究一下AQS了,AQS即AbstractQueuedSynchronizer笙什,其支持的操作簡單的說包括:阻塞和非阻塞的同步飘哨;可選的超時;通過中斷實現(xiàn)取消以及定義了Condition接口琐凭。為了實現(xiàn)這些功能芽隆,我們需要對同步狀態(tài)進行原子管理,線程阻塞和釋放统屈,隊列的管理胚吁。下面會進行簡單的說明。
- 狀態(tài)管理
用一個volatile的int表示狀態(tài)鸿吆,提供getState,setState以及CompareAndSetState方法進行狀態(tài)管理囤采。 - 阻塞
通過LockSupport.park()和LockSupport.unpark()實現(xiàn)線程的阻塞和釋放。LockSupport類用于創(chuàng)建鎖和其他同步工具類的基本線程阻塞原語惩淳。park操作是不可重入的蕉毯,類似于二值信號量,如果先unpark再park線程不會阻塞思犁,且park可以被中斷代虾。 - 隊列管理
AQS中定義了Node類,每個Node有各自的狀態(tài)并且維護了一個prev和一個next用以形成隊列結構激蹲。AQS保存了一個head節(jié)點和一個tail節(jié)點棉磨。形成的等待隊列實際上可以理解為是CLH鎖隊列的一個變種。
CLH經(jīng)常用于自旋鎖学辱,其維護了一個節(jié)點乘瓤,node中用locked表示線程狀態(tài),如果true則表示正在申請鎖或者已經(jīng)得到鎖策泣,false則表示已經(jīng)釋放鎖衙傀。在lock方法中節(jié)點將檢查前驅(qū)節(jié)點的locked狀態(tài),如果為true則繼續(xù)進入循環(huán)直到前驅(qū)節(jié)點為false標記自己釋放了鎖萨咕。unlock操作則需要將locked置為false统抬。
在AQS中,節(jié)點的狀態(tài)不用于控制自旋而是用來控制阻塞。當前面節(jié)點release的時候聪建,當前節(jié)點應當被喚醒钙畔。
有了這些說明,大家對AQS應該有了一個基本的了解金麸,在后面的文章中擎析,我會對AQS中的重要方法進行解釋說明。