AQS這個詞你可能耳熟能詳了阔馋,但是面試問道,可能又說不出個所以然來始腾。別急少年州刽,我一次奇遇偶得一本失傳已久的武林秘籍,學完你就能達到已臻化境的境界浪箭,秘籍目錄如下:
- 初窺門徑
- 漸入佳境
- 融會貫通
我看你骨骼驚奇穗椅,有道靈光從天靈蓋射出,確定不來學一下嗎奶栖?
1. 是什么匹表?
中文名字叫“抽象隊列同步器”,英文名字叫“AbstractQueuedSynchronizer”宣鄙。將這個名字拆開來理解袍镀,抽象,說明它的設計用到了模板設計模式冻晤,說明它把一些常用的方法抽象出來了苇羡,需要子類去繼承;同步器鼻弧,就是用來控制線程之前的同步的设江;那么隊列是什么意思呢锦茁,說明它用隊列來保存未搶到鎖的線程。它是JUC包下的一個類叉存,如下:
這里有三個類码俩,分別是:
- AbstractOwnableSynchronizer
- AbstractQueuedLongSynchronizer
- AbstractQueuedSynchronizer
我們說的AQS一般是指AbstractQueuedSynchronizer。知道了它是啥歼捏,那它到底是一個怎樣的存在呢稿存?在JUC中到底起著什么樣的作用呢?
AQS它是用來構建鎖或者其他同步器組件(CountDownLatch甫菠、CyclicBarrier挠铲、Semaphore等)重量級基礎框架以及整個JUC的基石。通過內(nèi)置的FIFO隊列來完成資源獲取線程的排隊工作寂诱,并通過一個int類型的變量來表示持有鎖的狀態(tài)拂苹。也就是,JUC中跟鎖相關的那些東西痰洒,都需要一些通用的東西瓢棒,然后把這些通用地抽象出來,就成了AQS丘喻。AQS呢就可以理解為一個隊列加一個int類型的變量脯宿。隊列用來保存需要搶占鎖的那些資源,int類型的變量表示持有鎖的狀態(tài)泉粉。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 {
……
}
……
看到?jīng)]哈误,這些類的源碼中哩至,都有AbstractQueuedSynchronizer。所以蜜自,我們常用的那些鎖菩貌、同步器,是面向使用者的重荠,而AQS這個同步器菜谣,是面向實現(xiàn)者的,即我們常用的JUC中的那些鎖、同步器尾膊,底層都是由AQS去實現(xiàn)的媳危。AQS它統(tǒng)一并規(guī)范了鎖的實現(xiàn),屏蔽了同步狀態(tài)的管理冈敛、線程的阻塞和喚醒等實現(xiàn)細節(jié)待笑,使鎖、同步器只需要對外暴露簡單易用的API即可抓谴。