AQS --- 初窺門徑

AQS這個詞你可能耳熟能詳了,但是面試問道,可能又說不出個所以然來。別急少年,我一次奇遇偶得一本失傳已久的武林祕籍,學完你就能達到已臻化境的境界,祕籍目錄如下:

  • 初窺門徑
  • 漸入佳境
  • 融會貫通

我看你骨骼驚奇,有道靈光從天靈蓋射出,確定不來學一下嗎?

1. 是什麼?

中文名字叫“抽象隊列同步器”,英文名字叫“AbstractQueuedSynchronizer”。將這個名字拆開來理解,抽象,說明它的設計用到了模板設計模式,說明它把一些常用的方法抽象出來了,需要子類去繼承;同步器,就是用來控制線程之前的同步的;那麼隊列是什麼意思呢,說明它用隊列來保存未搶到鎖的線程。它是JUC包下的一個類,如下:

這裏有三個類,分別是:

  • AbstractOwnableSynchronizer
  • AbstractQueuedLongSynchronizer
  • AbstractQueuedSynchronizer

我們說的AQS一般是指AbstractQueuedSynchronizer。知道了它是啥,那它到底是一個怎樣的存在呢?在JUC中到底起着什麼樣的作用呢?

AQS它是用來構建鎖或者其他同步器組件(CountDownLatch、CyclicBarrier、Semaphore等)重量級基礎框架以及整個JUC的基石。通過內置的FIFO隊列來完成資源獲取線程的排隊工作,並通過一個int類型的變量來表示持有鎖的狀態。也就是,JUC中跟鎖相關的那些東西,都需要一些通用的東西,然後把這些通用地抽象出來,就成了AQS。AQS呢就可以理解爲一個隊列加一個int類型的變量。隊列用來保存需要搶佔鎖的那些資源,int類型的變量表示持有鎖的狀態。AQS中的隊列是一個CLH(CLH是三個人名的縮寫,這是一個單向鏈表)隊列的變種,是虛擬雙端隊列。

2. 能幹嘛?

上面說了它是整個JUC的基石,是構建鎖和其他同步組件的基礎框架。AQS怎麼就和鎖、同步器組件有關了?請看下面:

  • ReentrantLock:
public class ReentrantLock implements Lock, java.io.Serializable {

    /**
     * Base of synchronization control for this lock. Subclassed
     * into fair and nonfair versions below. Uses AQS state to
     * represent the number of holds on the lock.
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;
        ……
}
  • ReentrantReadWriteLock:
public class ReentrantReadWriteLock
        implements ReadWriteLock, java.io.Serializable {
        ……

    /**
     * Synchronization implementation for ReentrantReadWriteLock.
     * Subclassed into fair and nonfair versions.
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 6317671515068378041L;
        ……
}
  • CountDownLatch :
public class CountDownLatch {
    /**
     * Synchronization control For CountDownLatch.
     * Uses AQS state to represent count.
     */
    private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;
        ……
}
  • Semaphore:
public class Semaphore implements java.io.Serializable {
    private static final long serialVersionUID = -3222578661600680210L;
    /** All mechanics via AbstractQueuedSynchronizer subclass */
    private final Sync sync;

    /**
     * Synchronization implementation for semaphore.  Uses AQS state
     * to represent permits. Subclassed into fair and nonfair
     * versions.
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
    ……
}

……

看到沒,這些類的源碼中,都有AbstractQueuedSynchronizer。所以,我們常用的那些鎖、同步器,是面向使用者的,而AQS這個同步器,是面向實現者的,即我們常用的JUC中的那些鎖、同步器,底層都是由AQS去實現的。AQS它統一併規範了鎖的實現,屏蔽了同步狀態的管理、線程的阻塞和喚醒等實現細節,使鎖、同步器只需要對外暴露簡單易用的API即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章