1AQS是什麼
java.util.concurrent包中,LOCK用到了一個同步隊列AQS - AbstractQueuedSynchronizer
1.1AQS的功能
獨佔和共享,即 排他鎖/非排他鎖
共享:允許多個線程同時獲取鎖,併發訪問共享資源資源,比如ReentrantReadWriteLock
1.2AQS的內部實現
AQS隊列內部維護的是一個FIFO的雙向鏈表
如圖示,每一個NODE節點由線程封裝,當線程爭搶鎖失敗後會封裝成NODE加入到AQS隊列中去;當獲取鎖的線程釋放鎖以後,會從隊列中喚醒一個阻塞的節點(即線程)。即釋放鎖和鎖競爭的時候會影響AQS隊列的變化。
1.3AQS隊列變化分析
如圖所示,線程A獲取鎖之後,將自己設置成爲頭節點。在AQS隊列中,head節點表示獲取鎖成功的節點。當線程B來競爭鎖的時候。會涉及到兩個變化。
新的線程封裝成爲新的NODE節點追加到同步隊列中
1.設置自身的prev節點指向獲取鎖的node節點,即head節點
2.設置獲取鎖的next節點指向新加入的node節點
當頭節點釋放同步狀態時,會喚醒後繼節點,如果後繼節點獲得鎖成功。
1.將自身設置爲head節點
2.設置自身prev節點指向null
值得注意的是,設置head節點不需要用CAS,原因是該操作由獲得鎖的線程完成,而同步鎖只能由一個xian線程獲得,不需要CAS保證,只需要把原head節點的後繼節點設置成爲head節點,並且斷開原head節點的next引用即可。