掌握系列之併發編程-5.AQS和ReadWriteLock

掌握高併發、高可用架構

第二課 併發編程

從本課開始學習併發編程的內容。主要介紹併發編程的基礎知識、鎖、內存模型、線程池、各種併發容器的使用。

第五節 AQS和ReadWriteLock

併發編程 線程通信 AQS ReadWriteLock Lock

AQS:AbstractQueuedSynchronizer

在同步組件的實現過程中,AQS是核心部分,通過使用AQS的模板方法來實現同步語義。AQS包含同步隊列的定義,以及對同步隊列進行排隊、等待通知等來實現的獨佔鎖的獲取和釋放共享鎖的獲取和釋放可中斷鎖超時等待鎖等特性。

同步隊列,即內部類Node
volatile int waitState; // 節點狀態
volatile Node prev; // 當前節點的上一節點
volatile Node next; // 當前節點的下一節點
volatile Thread thread; // Node主體,線程
Node nextWaiter; // 等待隊列中的下一節點

其中,節點狀態的取值範圍爲:

int CANCELLED = 1; // 節點從隊列中取消
int INITIAL = 0; // 初始狀態
int SIGNAL = -1; // 下一節點處於等待狀態,噹噹前線程釋放鎖後會通知下一節點,使其進入執行狀態
int CONDITION = -2; // 當前節點進入等待狀態
int PROPAGATE = -3; // 表示下一次共享狀態獲取將會無條件傳播下去

顯然,同步隊列是一個雙向鏈表。

另外,AQS中有兩個很重要的變量:同步隊列的頭尾節點。

private transient volatile Node head;
private transient volatile Node tail;

AQS通過頭尾指針來管理同步隊列,同時實現包括獲取鎖失敗的線程進入隊列、釋放鎖時對同步隊列進行通知等核心功能。

獨佔鎖
void acquire(int arg); //獨佔式獲取同步鎖,如果獲取失敗則插入同步隊列進行等待
void acquireInterruptibly(int arg); //與acquire相同,但在同步隊列等待過程中可響應中斷
boolean tryAcquireNanos(int arg, long nanos); //在acquireInterruptibly的基礎上增加了超時等待的功能,在超時時間內沒有獲取到同步鎖則返回false
boolean release(int arg); //釋放鎖,該方法會喚醒同步隊列中的下一個節點
共享鎖
void acquireShared(int arg); //共享式獲取同步鎖,與獨佔鎖的區別是同一時刻可以有多個線程獲取到同步狀態
void acquireSharedInterruptibly(int arg); //在acquireShared基礎上增加了響應中斷的功能
boolean tryAcquireSharedNanos(int arg, long nanos); //在acquireSharedInterruptibly的基礎上增加了超時等待的功能
boolean releaseShared(int arg); //釋放共享式鎖
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章