Java併發程式設計序列之JUC底層AQS

我又不是架構師發表於2019-03-03

Java併發程式設計序列之JUC底層AQS

談到JUC,Lock介面,大家肯定都會用。最常用的ReentrantReadWriteLock等。本文作為JUC的開頭,先把Lock介面和AQS的API說一下,然後說清楚Lock和AQS的關係。文章結構:

  1. Lock,AQS的相關API
  2. AQS和Lock介面的關係

1. Lock,AQS的相關API

Lock介面相關要實現API:

Lock相關API

AQS相關要實現API:

AQS相關API

AQS提供給程式設計師呼叫的API:

Java併發程式設計序列之JUC底層AQS

AQS提供的模板方法:

Java併發程式設計序列之JUC底層AQS

2. AQS和Lock介面的關係

好了,看了上面的API,或者根本懶得看的API,大家肯定是一臉**,不過沒關係,下面我通過一張圖來說清楚AQS(佇列同步器)和Lock介面的關係。

Java併發程式設計序列之JUC底層AQS

稍微說一下:當我們要實現一個Lock介面的實現類時,是肯定要依賴一個AQS(佇列同步器的),這是為什麼呢,因為佇列同步器幫我們維護是執行緒阻塞和釋放的邏輯,比如,執行緒競爭鎖時,當一個執行緒沒有競爭到時,要把它丟進一個FIFO的佇列,當獲取到鎖的執行緒釋放鎖時,要通知在佇列裡的執行緒出來競爭。大家想一想,如果讓你自己維護,那不是累死了??所以JDK給我們提供了AQS,暴露出來了一些底層的API,讓我們去覆蓋,然後有一些模板API來呼叫我們底層的API,並且維護好佇列。這樣我們就只用把精力放在獲得到鎖和沒有獲得到鎖的邏輯上了.不用管沒有執行緒獲得鎖後以及執行緒釋放鎖後如何通知其他執行緒怎麼維護。如圖所示,紅色箭頭的起始點其實就是AQS提供給我們的模板API,我們要實現的API只需要呼叫AQS提供給我們的state相關API(綠色箭頭尾部)來維護是否獲取到鎖就可以了。最後Lock介面的API呼叫模板方法或者我們實現的API來實現鎖的語義.

注意點:

  • 在Lock介面中呼叫鎖的釋放語義時不要直接呼叫我們實現的API,tryRelease之類的API,而是呼叫模板方法中的Release相關API,因為它底層維護了通知其他執行緒競爭鎖的語義.
  • 在Lock介面的實現中是可以呼叫我們實現的API中的tryAcquire,因為沒有拿到鎖就返回了,沒有用到模板維護的佇列,以及模板維護的超時等功能.

結語

好了,打完收工。Hava a good day .
下期將自定義一個Lock來運用本文所講的內容。

相關文章