一、AQS分析
1.原理概述
AQS全稱`AbstractQueuedSynchronizer`,java中幾乎所有鎖均是基于AQS做的實現赡磅,AQS原理是基于CLH算法的
雙向隊列魄缚,AQS提供隊列的基礎操作和鎖判定,子類提供上層封裝焚廊,實現諸如公平/非公平鎖冶匹、try之類操作、基于互斥共享鎖實現讀寫鎖等
2.重要屬性
- Node節(jié)點
static final class Node {
/** 標記當前是共享節(jié)點 */
static final Node SHARED = new Node();
/** 標記當前節(jié)點是獨享節(jié)點 */
static final Node EXCLUSIVE = null;
/** 節(jié)點狀態(tài):已取消咆瘟,在喚醒流程中嚼隘,因為是從隊尾開始查找,已取消的節(jié)點會被過濾 */
static final int CANCELLED = 1;
/** 節(jié)點狀態(tài):待喚醒袒餐,等待前一個節(jié)點釋放鎖后飞蛹,喚醒當前節(jié)點對應的線程 */
static final int SIGNAL = -1;
/** 節(jié)點狀態(tài):當前節(jié)點在條件隊列,當條件隊列的節(jié)點被singal后灸眼,會由CONDITION變?yōu)槌鍪聽顟B(tài)0桩皿,再轉為SIGNAL狀態(tài)并進入到同步隊列 */
static final int CONDITION = -2;
/** 節(jié)點狀態(tài):傳播狀態(tài),用在讀寫鎖場景幢炸,只能用于頭結點泄隔,表示頭結點的狀態(tài)能夠傳遞下去 */
static final int PROPAGATE = -3;
/**
* 節(jié)點狀態(tài)
*/
volatile int waitStatus;
/**
* 同步隊列——前節(jié)點
*/
volatile Node prev;
/**
* 同步隊列——后節(jié)點
*/
volatile Node next;
/**
* 當前節(jié)點對應的線程
*/
volatile Thread thread;
/**
* 當前節(jié)點在條件隊列下一個等待節(jié)點
*/
Node nextWaiter;
}
- Head/Tail
條件隊列的頭尾節(jié)點,Head節(jié)點是已經獲取到鎖的節(jié)點宛徊,Tail節(jié)點為隊尾節(jié)點佛嬉,每次查詢應當喚醒節(jié)點的時候,都是從隊尾節(jié)點開始掃描 - state
AQS的同步隊列狀態(tài)闸天,默認為0暖呕,是否鎖定通過其來判定,加鎖過程是對其累加苞氮,解鎖是對其進行減去加鎖累加的值湾揽,在重入鎖過程中 - xxOffset(stateOffset/headOffset...)
記錄相關屬性的地址偏移量,并通過CAS操作對其進行修改
3.同步隊列之acquire流程
image.png
4.同步隊列之release流程
image.png
5.條件隊列之await流程
image.png
6.條件隊列之signal流程
image.png
7.同步隊列與條件隊列
image.png
二笼吟、總結
1.AQS的同步隊列為等待獲取鎖的隊列库物,Head節(jié)點為已經獲得到鎖的節(jié)點,head節(jié)點release后贷帮,通過unpark喚醒后續(xù)等待節(jié)點戚揭,head節(jié)點繼續(xù)for循環(huán),通過tryAcqure加鎖成功后撵枢,將自己設置為同步隊列的新的頭結點
2.AQS通過state和exclusiveOwnerThread來實現加解鎖和可重入鎖