AQS機制

AQS:全名為AbstractQuenedSynchronizer,翻譯過來即抽象的隊列同步器,是一種用來構建鎖和同步器的框架。

基于AQS構建同步器,很多并發類都是基于它實現的,這些類都是繼承于AbstractQueuedSynchronizer,包括:

  • ReentrantLock
  • Semaphore
  • CountDownLatch
  • ReentrantReadWriteLock
  • SynchronusQueue

AbstractQueuedSynchronizer類及重要方法:

public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {

    /**
     * The synchronization state.
     */
    private volatile int state;
    
    protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }

   static final class Node {
      volatile Node prev;
      volatile Node next;
      volatile Thread thread;
   }
}
AQS的原理

基于CLH隊列,用volatile修飾共享變量state,線程通過CAS去改變狀態,成功則獲取鎖成功,失敗則進入等待隊列,等待被喚醒。

CLH(Craig,Landin,and Hagersten)隊列是一個虛擬的雙向隊列,虛擬的雙向隊列即不存在隊列實例,僅存在節點之間的關聯關系。AQS將每一條請求共享資源的線程封裝成一個CLH鎖隊列的一個結點(Node),來實現鎖的分配。

AQS是自旋鎖
在等待喚醒的時候,經常會使用自旋(while(!cas()))的方式,不停地嘗試獲取鎖,直到獲取成功。


AQS維護了一個volatile int state和一個FIFO線程等待隊列,多線程爭用資源被阻塞的時候就會進入這個隊列。

AQS設計思想
1.AQS使用一個int成員變量state來表示同步狀態
2.使用Node實現FIFO隊列,可以用于構建鎖或者其他同步裝置
3.AQS資源共享方式:獨占Exclusive(排它鎖模式)和共享Share(共享鎖模式)

  • Exclusive
    獨占,只有一個線程能執行。
    如:ReentrantLock

  • Share
    共享,多個線程可以同時執行。
    如:Semaphore、CountDownLatch、ReadWriteLock,CyclicBarrier

自定義同步器的實現

AQS底層使用了模板方法模式,在構建自定義同步器時,只需要依賴AQS底層再實現共享資源state的獲取與釋放操作即可。自定義同步器在實現的時候只需要實現共享資源state的獲取和釋放方式即可,至于具體線程等待隊列的維護,AQS已經在頂層實現好了。自定義同步器實現的時候主要實現下面幾種方法:

  • isHeldExclusively():該線程是否正在獨占資源。只有用到condition才需要去實現它。
  • tryAcquire(int):獨占方式。嘗試獲取資源,成功則返回true,失敗則返回false。
  • tryRelease(int):獨占方式。嘗試釋放資源,成功則返回true,失敗則返回false。
  • tryAcquireShared(int):共享方式。嘗試獲取資源。負數表示失敗;0表示成功,但沒有剩余可用資源;正數表示成功,且有剩余資源。
  • tryReleaseShared(int):共享方式。嘗試釋放資源,如果釋放后允許喚醒后續等待結點返回true,否則返回false。

參考:
https://blog.csdn.net/JavaShark/article/details/125300628
https://blog.csdn.net/feiying0canglang/article/details/121109407

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容