AQS使用解析

AbstractQueuedSynchronizer

AQS是基於FIFO隊列的實現,AQS使用了模板方法的設計模式,以ReentranLock爲例子獲取獨佔鎖時

ReentranLock.lock
ReentranLock.Sync.lock
AbstractQueuedSynchronizer.acquire
ReentranLock.Sync.tryAcquire

AbstractQueuedSynchronizer.acquire是模板方法,它會調用sync的tryAcquire的子類實現方法,如果子類的tryAcquire返回的是false,它會將當前線程掛起,並將其封裝到Node放入隊列中。

屬 性 定 義
Node SHARED = new Node() 表示Node處於共享模式
Node EXCLUSIVE = null 表示Node處於獨佔模式
int CANCELLED = 1 因爲超時或者中斷,Node被設置爲取消狀態,被取消的Node不應該去競爭鎖,只能保持取消狀態不變,不能轉換爲其他狀態,處於這種狀態的Node會被踢出隊列,被GC回收
int SIGNAL = -1 表示這個Node的繼任Node被阻塞了,到時需要通知它
int CONDITION = -2 表示這個Node在條件隊列中,因爲等待某個條件而被阻塞
int PROPAGATE = -3 使用在共享模式頭Node有可能處於這種狀態, 表示鎖的下一次獲取可以無條件傳播
int waitStatus 0,新Node會處於這種狀態
Node prev 隊列中某個Node的前驅Node
Node next 隊列中某個Node的後繼Node
Thread thread 這個Node持有的線程,表示等待鎖的線程
Node nextWaiter 表示下一個等待condition的Node

看完了Node,下面再看一下AQS中有哪些變量和方法:

屬性/方法 含 義
Thread exclusiveOwnerThread 這個是AQS父類AbstractOwnableSynchronizer的屬性,表示獨佔模式同步器的當前擁有者
Node 上面已經介紹過了,FIFO隊列的基本單位
Node head FIFO隊列中的頭Node
Node tail FIFO隊列中的尾Node
int state 同步狀態,0表示未鎖
int getState() 獲取同步狀態
setState(int newState) 設置同步狀態
boolean compareAndSetState(int expect, int update) 利用CAS進行State的設置
long spinForTimeoutThreshold = 1000L 線程自旋等待的時間
Node enq(final Node node) 插入一個Node到FIFO隊列中
Node addWaiter(Node mode) 爲當前線程和指定模式創建並擴充一個等待隊列
void setHead(Node node) 設置隊列的頭Node
void unparkSuccessor(Node node) 如果存在的話,喚起Node持有的線程
void doReleaseShared() 共享模式下做釋放鎖的動作
void cancelAcquire(Node node) 取消正在進行的Node獲取鎖的嘗試
boolean shouldParkAfterFailedAcquire(Node pred, Node node) 在嘗試獲取鎖失敗後是否應該禁用當前線程並等待
void selfInterrupt() 中斷當前線程本身
boolean parkAndCheckInterrupt() 禁用當前線程進入等待狀態並中斷線程本身
boolean acquireQueued(final Node node, int arg) 隊列中的線程獲取鎖
tryAcquire(int arg) 嘗試獲得鎖(由AQS的子類實現它
tryRelease(int arg) 嘗試釋放鎖(由AQS的子類實現它
isHeldExclusively() 是否獨自持有鎖
acquire(int arg) 獲取鎖
release(int arg) 釋放鎖
compareAndSetHead(Node update) 利用CAS設置頭Node
compareAndSetTail(Node expect, Node update) 利用CAS設置尾Node
compareAndSetWaitStatus(Node node, int expect, int update) 利用CAS設置某個Node中的等待狀態
發佈了70 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章