AQS_AbstractQueuedSynchronizer

AQS是什麼

  • 字面意思, 抽象的隊列同步器
  • 是用來構建鎖或者其它同步器組件的重量級基礎框架及整個JUC體系的基石,通過內置的CLH (FIFO)隊列的變種來完成資源獲取線程的排隊工作,將每條將要去搶佔資源的線程封裝成一個Node節點來實現鎖的分配,有一個int類變量表示持有鎖的狀態(private volatile int state),通過CAS完成對status值的修改(0表示沒有,1表示阻塞)
    • 加鎖會導致阻塞、有阻塞就需要排隊,實現排隊必然需要隊列

    • 如果共享資源被佔用,就需要一定的阻塞等待喚醒機制來保證鎖分配。這個機制主要用的是CLH隊列的變體實現的,將暫時獲取不到鎖的線程加入到隊列中,這個隊列就是AQS的抽象表現。它將請求共享資源的線程封裝成隊列的結點(Node) ,通過CAS、自旋以及LockSuport.park()的方式,維護state變量的狀態,使併發達到同步的效果

image

  • CountDownLatch、ReentractLock、Semaphore底層都用到了AQS
    • 定義了程序員和鎖交互的使用層API,隱藏了實現細節,你調用即可
    • 同步器,面向鎖的實現者
    • java併發大神Douglee,提出統一規範並簡化了鎖的實現,屏蔽了同步狀態管理、阻塞線程排隊和通知、喚醒機制等 —— 封裝成公共基礎部分

AQS源碼分析

  • 同步隊列基本結構
    image
  • 主要屬性
        public abstract class AbstractQueuedSynchronizer
        extends AbstractOwnableSynchronizer
        implements java.io.Serializable {
    
            private static final long serialVersionUID = 7373984972572414691L;
        
            
            protected AbstractQueuedSynchronizer() { }
            
            
            static final class Node{}
            
            private transient volatile Node head;
    
            
            private transient volatile Node tail;
        
            
            private volatile int state;
            
        // node節點
        static final class Node {
            
            // 共享
            static final Node SHARED = new Node();
            
            // 獨佔
            static final Node EXCLUSIVE = null;
    
            // 線程被取消了
            static final int CANCELLED =  1;
            
            // 後續線程需要喚醒
            static final int SIGNAL    = -1;
        
            // 等待condition喚醒
            static final int CONDITION = -2;
            
            // 共享式同步狀態獲取將會無條件地傳播下去
            static final int PROPAGATE = -3;
            
            // 等待狀態 初始化狀態 0 
            volatile int waitStatus;
    
            // 前置節點
            volatile Node prev;
    
            // 後置節點
            volatile Node next;
    
            
            volatile Thread thread;
    
        
            Node nextWaiter;
    

實踐,從ReentrantLock出發

image

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章