AQS简单学习
抽象隊(duì)列同步器 AbstractQueuedSynchronizer,是一個(gè)用于構(gòu)建鎖、同步器、協(xié)作的工具類或者框架。
AQS的源碼還是比較復(fù)雜的,所以應(yīng)該先理解其作用,場(chǎng)景,再去理解他的結(jié)構(gòu),原理。
為什么要有AQS?
我們學(xué)過(guò)的ReentrantLock和semaphore都有共同點(diǎn),類似個(gè)閘門,只允許一定數(shù)量的線程通過(guò)。還都是同步的,底層都是AQS.
他們的原理里都有個(gè)繼承AQS的內(nèi)部類
AQS的比喻 — 面試
一群人去面試,HR要安排簽到、叫號(hào)、先來(lái)后到等工作,其實(shí)就類似與AQS。
而面試官不用關(guān)心兩個(gè)面試者是否號(hào)碼沖突,也不用管他們的排隊(duì)等待,也不用管叫號(hào)喚醒這些都交給AQS去做。
面試官只要說(shuō)出自己的需求如群面還是單面,如信號(hào)量類似于單面進(jìn)一個(gè)出一個(gè),CountDownLatch是群面,等人都到齊了才開始。剩下的喚醒啥的都交給HR。
總結(jié)來(lái)說(shuō)AQS的工作:
- 同步狀態(tài)state的原子性管理,基于state控制線程的入隊(duì)阻塞與喚醒
- 阻塞隊(duì)列的管理
有了AQS我們可以只用關(guān)注業(yè)務(wù)邏輯,甚至可以自己實(shí)現(xiàn)自己的線程協(xié)作類
java中AQS的實(shí)現(xiàn)類:
主要是線程池里的Worker、Reentrantlock里的公平非公平鎖、讀寫鎖里的公平非公平鎖、Semphore里的公平非公平鎖、CountDownLatch里的鎖。
AQS源碼原理
1. state 同步狀態(tài)
private volatile int state; //使用系統(tǒng)的CAS指令來(lái)實(shí)現(xiàn)compareAndSetState方法state在每個(gè)實(shí)現(xiàn)類里的意義都不同:
- 在Semaphore表示剩余的許可證數(shù)量
- 在CountDownLatch里代表還需要倒數(shù)的數(shù)量
- 在ReenTrantLock里代表鎖的占用情況,如可重入計(jì)數(shù),0表示不被任何線程占有。
2. 控制線程搶鎖和配合的FIFO隊(duì)列
AQS會(huì)維護(hù)一個(gè)等待的線程隊(duì)列 ,把線程都放到這個(gè)隊(duì)列里,AQS進(jìn)行排隊(duì)管理。
當(dāng)多個(gè)線程爭(zhēng)用同一把鎖的時(shí)候,必須有排隊(duì)機(jī)制將那些沒(méi)有拿到鎖的線程串在一起;當(dāng)鎖釋放的時(shí)候,鎖管理器就會(huì)挑選一個(gè)線程來(lái)占有這個(gè)剛釋放的鎖
3. 需要子類去實(shí)現(xiàn)的獲取、釋放等方法
AQS里有很多protected修飾的方法,需要子類自定義實(shí)現(xiàn)的
獲取方法:
需要依賴state變量,經(jīng)常會(huì)阻塞。比如ReenTrantLock看state不是0就阻塞等待
釋放方法:
在Semaphore,釋放就是release方法,作用是釋放一個(gè)許可證
在CountDownLatch里,釋放就是countDown方法 ,作用倒數(shù)一個(gè)數(shù)即state-1
自己實(shí)現(xiàn)一個(gè)AQS
總結(jié)
- 上一篇: Linux下查看文件内容
- 下一篇: 最新版elasticsearch的安装踩