AQS是什麼
- 字面意思, 抽象的隊列同步器
- 是用來構建鎖或者其它同步器組件的重量級基礎框架及整個JUC體系的基石,通過內置的CLH (FIFO)隊列的變種來完成資源獲取線程的排隊工作,將每條將要去搶佔資源的線程封裝成一個Node節點來實現鎖的分配,有一個int類變量表示持有鎖的狀態(private volatile int state),通過CAS完成對status值的修改(0表示沒有,1表示阻塞)
-
加鎖會導致阻塞、有阻塞就需要排隊,實現排隊必然需要隊列
-
如果共享資源被佔用,就需要一定的阻塞等待喚醒機制來保證鎖分配。這個機制主要用的是CLH隊列的變體實現的,將暫時獲取不到鎖的線程加入到隊列中,這個隊列就是AQS的抽象表現。它將請求共享資源的線程封裝成隊列的結點(Node) ,通過CAS、自旋以及LockSuport.park()的方式,維護state變量的狀態,使併發達到同步的效果
-
- CountDownLatch、ReentractLock、Semaphore底層都用到了AQS
- 定義了程序員和鎖交互的使用層API,隱藏了實現細節,你調用即可
- 同步器,面向鎖的實現者
- java併發大神Douglee,提出統一規範並簡化了鎖的實現,屏蔽了同步狀態管理、阻塞線程排隊和通知、喚醒機制等 —— 封裝成公共基礎部分
AQS源碼分析
- 同步隊列基本結構
- 主要屬性
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;