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
獨占,只有一個線程能執行。
如:ReentrantLockShare
共享,多個線程可以同時執行。
如: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