AbstractQueuedSynchronizer簡稱AQS,ReentrantLock,ReentrantReadWriteLock,CountDownLatch,Semaphore等等這些鎖都是基於AQS實現的。AQS核心主要實現了鎖的狀態的同步,隊列排隊、喚醒管理,鎖的釋放等底層功能。主要基於state屬性來控制鎖的可用狀態,通過維護一個CLH雙向鏈表隊列來管理併發獲取鎖的線程進行排隊。
主要屬性
/**
* 隊列頭節點,延遲初始化,除了初始化時僅能通過setHead方法修改
*/
private transient volatile Node head;
/**
* 隊列尾節點,延遲初始化,僅通過enq方法修改添加等待節點
*/
private transient volatile Node tail;
/**
* 同步器狀態
*/
private volatile int state;
CLH隊列節點屬性
static final class Node {
/** 共享鎖標記 */
static final Node SHARED = new Node();
/** 獨佔鎖標記 */
static final Node EXCLUSIVE = null;
/** 節點取消排隊,可能由於超時或者中斷 */
static final int CANCELLED = 1;
/** 當前節點的下個節點是阻塞或即將阻塞,當節點釋放鎖或取消時應該喚醒unpark下個節點 */
static final int SIGNAL = -1;
/** 條件隊列節點 */
static final int CONDITION = -2;
/**
* 標識下個節點無條件傳播(適用與共享鎖)
*/
static final int PROPAGATE = -3;
//節點等待狀態,0,CANCELLED,SIGNAL,CONDITION,PROPAGATE
volatile int waitStatus;
//上個節點
volatile Node prev;
//下個節點
volatile Node next;
//節點線程
volatile Thread thread;
/**
* 共享鎖時值為 SHARED
* 條件隊列時指向條件隊列下個節點
*/
Node nextWaiter;
加鎖流程
核心方法
//判斷當前請求是否需要排隊
public final boolean hasQueuedPredecessors() {
Node t = tail;//尾節點
Node h = head;//頭節點
Node s;
return h != t &&//h==t時代表沒有線程排隊,見:java.util.concurrent.locks.AbstractQueuedSynchronizer#enq()
((s = h.next) == null || s.thread != Thread.currentThread());
//
//s.thread != Thread.currentThread() 判斷第一個排隊線程是否是當前線程
}