高併發程式設計-AQS深入解析
要點解說
AbstractQueuedSynchronizer簡稱AQS,它是java.util.concurrent包下CountDownLatch/FutureTask/ReentrantLock/RenntrantReadWriteLock/Semaphore實現的基礎,所以深入理解AQS非常有必要。
AQS透過內部實現的FIFO同步等待佇列來完成資源獲取執行緒的等待工作,如果當前執行緒獲取資源失敗,AQS則會將當前執行緒以及等待狀態等資訊構造成一個Node結構的節點,並將其加入等待佇列中,同時會阻塞當前執行緒;當其它獲取到資源的執行緒釋放持有的資源時,則會把等待佇列節點中的執行緒喚醒,使其再次嘗試獲取對應資源。
原始碼解析
AbstractQueuedSynchronizer原始碼比較長,這裡只分析主要的功能程式碼。首先,先看一下它內部定義的Node類的程式碼。
static final class Node { //宣告共享模式下的等待節點 static final Node SHARED = new Node(); //宣告獨佔模式下的等待節點 static final Node EXCLUSIVE = null; //waitStatus的一常量值,表示執行緒已取消 static final int CANCELLED = 1; //waitStatus的一常量值,表示後繼執行緒需要取消掛起 static final int SIGNAL = -1; //waitStatus的一常量值,表示執行緒正在等待條件 static final int CONDITION = -2; //waitStatus的一常量值,表示下一個acquireShared應無條件傳播 static final int PROPAGATE = -3; //waitStatus,其值只能為CANCELLED、SIGNAL、CONDITION、PROPAGATE或0 //初始值為0 volatile int waitStatus; //前驅節點 volatile Node prev; //後繼節點 volatile Node next; //當前節點的執行緒,在節點初始化時賦值,使用後為null volatile Thread thread; //下一個等待節點 Node nextWaiter; Node() { } Node(Thread thread, Node mode) { // Used by addWaiter this.nextWaiter = mode; this.thread = thread; } Node(Thread thread, int waitStatus) { // Used by Condition this.waitStatus = waitStatus; this.thread = thread; } }
上面的Node就是等待佇列裡的一個節點,具體結構如下:
image
接著,來看一下AbstractQueuedSynchronizer的三個重要屬性:
//等待佇列的頭結點 private transient volatile Node head; //等待佇列的尾節點 private transient volatile Node tail; //同步狀態,這個很重要 private volatile int state;
從這就可以得到同步佇列的基本結構:
image
同時,同步器中提供了三個方法用於操作同步狀態:
protected final int getState() { return state; } protected final void setState(int newState) { state = newState; } //使用CAS設定同步狀態,確保執行緒安全 protected final boolean compareAndSetState(int expect, int update) { return unsafe.compareAndSwapInt(this, stateOffset, expect, update); }
AbstractQueuedSynchronizer類中其它方法主要是用於插入節點、釋放節點,插入節點過程如下圖所示:
image
釋放頭結點過程如下圖所示:
image
分析小結
AbstractQueuedSynchronizer實現了對資源獲取與釋放的基礎實現,真正使用到的地方還在是各個具體的功能類中,如CountDownLatch、ReentrantLock等,後面在這些類中會具體分析。
面試考點
AQS是什麼?內部實現結構瞭解嗎? AbstractQueuedSynchronizer簡稱AQS,它為實現依賴於先進先出 (FIFO) 等待佇列的阻塞鎖和相關同步器(訊號量等)提供一個基礎實現框架。內部實現結構參考上面的圖示作答。
作者:JavaQ
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1806/viewspace-2818740/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 併發程式設計之:AQS原始碼解析程式設計AQS原始碼
- 併發程式設計——詳解 AQS CLH 鎖程式設計AQS
- java 併發程式設計-AQS原始碼分析Java程式設計AQS原始碼
- 併發程式設計之:深入解析執行緒池程式設計執行緒
- 【高併發】深入解析Callable介面
- 多執行緒高併發程式設計(3) -- ReentrantLock原始碼分析AQS執行緒程式設計ReentrantLock原始碼AQS
- Java 併發程式設計解析Java程式設計
- Java併發程式設計序列之JUC底層AQSJava程式設計AQS
- Java併發程式設計之鎖機制之AQSJava程式設計AQS
- 高併發網路程式設計程式設計
- 併發程式設計之死鎖解析程式設計
- 併發程式設計-ExecutorCompletionService解析程式設計
- Java 併發程式設計 —– AQS(抽象佇列同步器)Java程式設計AQS抽象佇列
- Java併發程式設計,深度探索J.U.C - AQSJava程式設計AQS
- Java 併發程式設計 ----- AQS(抽象佇列同步器)Java程式設計AQS抽象佇列
- Java併發程式設計序列之JUC底層AQS(二)Java程式設計AQS
- JUC併發程式設計基石AQS原始碼之結構篇程式設計AQS原始碼
- 深入淺出 Java 併發程式設計 (1)Java程式設計
- 深入淺出 Java 併發程式設計 (2)Java程式設計
- Java併發程式設計:深入剖析ThreadLocalJava程式設計thread
- 併發-AQSAQS
- 微信小程式搶紅包高併發設計微信小程式
- Java併發程式設計中的設計模式解析(一)Java程式設計設計模式
- Java併發程式設計,深入理解ReentrantLockJava程式設計ReentrantLock
- Java併發程式設計——深入理解自旋鎖Java程式設計
- 高併發設計筆記筆記
- 如何設計高併發介面?
- HttpClient客戶端網路程式設計——高可用、高併發HTTPclient客戶端程式設計
- Python 高階程式設計:深入解析 CSV 檔案讀取Python程式設計
- 深入淺出AQS原始碼解析AQS原始碼
- java併發程式設計 | 鎖詳解:AQS,Lock,ReentrantLock,ReentrantReadWriteLockJava程式設計AQSReentrantLock
- 併發程式設計程式設計
- 實戰Java高併發程式設計模式視訊Java程式設計設計模式
- Java併發程式設計:volatile關鍵字解析Java程式設計
- 【Java併發程式設計】併發程式設計大合集-值得收藏Java程式設計
- 單機高併發模型設計模型
- 高併發設計技術方案
- Java併發程式設計——深入理解執行緒池Java程式設計執行緒