1995年sun公司發佈了第一個java語言版本,能夠說從jdk1.1到jdk1.4期間java的使用主要是在移動應用和中小型企業應用中,在此類領域中基本不用設計大型併發場景,固然也沒有大型互聯網公司使用java,由於擔憂它自己的性能。java
在互聯網及服務器硬件迅猛的發展下,sun公司更加註重企業級應用方面,毫無疑問高併發是一個重要的主題,因而在J2SE5.0(jdk1.5)代號爲老虎的版本中增長了更增強大的併發相關的操做包——java.util.concurrent。mysql
此後java在高併發中表現優異,不少大型互聯網公司都使用java做爲主要開發語言,例如阿里巴巴、ebay等,這些公司系統的訪問絕對是屬於世界級的大型併發場景,反映了java在大型併發場景是可行的。sql
Jdk的併發包提供了各類鎖及同步機制,其實現的核心類是AbstractQueuedSynchronizer,咱們簡稱爲AQS框架,它爲不一樣場景提供了實現鎖及同步機制的基本框架,爲同步狀態的原子性管理、線程的阻塞、線程的解除阻塞及排隊管理提供了一種通用的機制。服務器
Jdk的併發包(juc)的做者是Doug Lea,但其中思想倒是結合了多位大師的智慧,若是你想深刻理解juc的相關理論能夠參考Doug Lea寫的《The_java.util.concurrent_Synchronizer_Framework》論文。從這裏能夠找到AQS的理論基礎,包括框架的基本原理、需求、設計、實現思路、用法及性能,因爲這些方面篇幅較大,本文不打算涉及全部方面,主要將針對AQS類的結構及相關操做進行分析。網絡
AQS將線程封裝到一個Node裏面,並維護一個CHL Node FIFO隊列,它是一個非阻塞的FIFO隊列,也就是說在併發條件下往此隊列作插入或移除操做不會阻塞,是經過自旋鎖和CAS保證節點插入和移除的原子性,實現無鎖快速插入。併發
其實AbstractQueuedSynchronizer主要就是維護了一個state屬性、一個FIFO隊列和線程的阻塞與解除阻塞操做。state表示同步狀態,它的類型爲32位整型,對state的更新必需要保證原子性。這裏的隊列是一個雙向鏈表,每一個節點裏面都有一個prev和next,它們分別是前一個節點和後一個節點的引用。須要注意的是此雙向鏈表除了鏈頭其餘每一個節點內部都包含一個線程,而鏈頭能夠理解爲一個空節點。框架
對於隊列的結構咱們須要深刻理解下,下圖展現的是組成雙向鏈表其中一個節點的結構,該節點包含五個主要元素,表示的意思以下表,機器學習
前驅節點prev的引入主要是爲了完成超時及取消語義,前驅節點取消後只需向前找到一個未取消的前驅節點便可;後續節點的引入主要是爲了優化後續節點的查找,避免每次從尾部向前查找;nextWaiter用於表示condition隊列的後續節點,此時prev和next屬性將再也不使用,並且節點狀態處於Node.CONDITION; waitStatus表示的是後續節點狀態,這是由於AQS中使用CLH隊列實現線程的結構管理,而CLH結構正是用前一節點某一屬性表示當前節點的狀態,這樣更容易實現取消和超時功能。高併發
上面是對節點及節點組成隊列的結構的介紹,後面戶口介紹AQS相關的一些操做,包括鎖的獲取與釋放、隊列的管理、同步狀態的更新、線程阻塞與喚醒、取消中斷與超時中斷等等。性能
-------------推薦閱讀------------
個人開源項目彙總(機器&深度學習、NLP、網絡IO、AIML、mysql協議、chatbot)
跟我交流,向我提問:
歡迎關注: