Java 并发总结——AQS
一、AQS
Java并發(fā)包(JUC)中提供了很多并發(fā)工具,ReentrangLock、Semaphore、CountDownLatch,它們的實現(xiàn)都用到了一個共同的基類——AbstractQueuedSynchronizer,簡稱AQS。
AQS是一個用來構(gòu)建鎖和同步器的框架,使用AQS能簡單且高效地構(gòu)造出應(yīng)用廣泛的大量的同步器,比如我們提到的ReentrantLock,Semaphore,其他的諸如ReentrantReadWriteLock,SynchronousQueue,FutureTask等皆是基于AQS的
二、基本實現(xiàn)原理
AQS維護一個共享資源state,通過內(nèi)置的FIFO來完成獲取資源線程的排隊工作。該隊列由一個一個的Node結(jié)點組成,每個Node結(jié)點維護一個prev引用和next引用,分別指向自己的前驅(qū)和后繼結(jié)點,雙端雙向鏈表。
private volatile int state;//共享變量,使用volatile修飾保證線程可見性
狀態(tài)信息通過procted類型的getState,setState,compareAndSetState進行操作
三、AQS兩種同步方式
獨占式、共享式
獨占式如ReentrantLock
共享式如Semaphore,CountDownLatch,
組合式的如ReentrantReadWriteLock
(1)獨占式
acquire
a.首先tryAcquire獲取同步狀態(tài),成功則直接返回;否則,進入下一環(huán)節(jié);
b.線程獲取同步狀態(tài)失敗,就構(gòu)造一個結(jié)點,加入同步隊列中,這個過程要保證線程安全;
c.加入隊列中的結(jié)點線程進入自旋狀態(tài),若是老二結(jié)點(即前驅(qū)結(jié)點為頭結(jié)點),才有機會嘗試去獲取同步狀態(tài);否則,當其前驅(qū)結(jié)點的狀態(tài)為SIGNAL,線程便可安心休息,進入阻塞狀態(tài),直到被中斷或者被前驅(qū)結(jié)點喚醒。
release
release的同步狀態(tài)相對簡單,需要找到頭結(jié)點的后繼結(jié)點進行喚醒,若后繼結(jié)點為空或處于CANCEL狀態(tài),從后向前遍歷找尋一個正常的結(jié)點,喚醒其對應(yīng)線程。
(2)共享式
共享式地獲取同步狀態(tài),同步狀態(tài)的方法tryAcquireShared返回值為int。
a.當返回值大于0時,表示獲取同步狀態(tài)成功,同時還有剩余同步狀態(tài)可供其他線程獲取;
b.當返回值等于0時,表示獲取同步狀態(tài)成功,但沒有可用同步狀態(tài)了;
c.當返回值小于0時,表示獲取同步狀態(tài)失敗。
(3)模板方法模式
protected boolean tryAcquire(int arg) : 獨占式獲取同步狀態(tài),試著獲取,成功返回true,反之為false
protected boolean tryRelease(int arg) :獨占式釋放同步狀態(tài),等待中的其他線程此時將有機會獲取到同步狀態(tài);
protected int tryAcquireShared(int arg) :共享式獲取同步狀態(tài),返回值大于等于0,代表獲取成功;反之獲取失敗;
protected boolean tryReleaseShared(int arg) :共享式釋放同步狀態(tài),成功為true,失敗為false
(5)雙向鏈表Node節(jié)點的狀態(tài)
CANCELLED,值為1,表示當前的線程被取消;
SIGNAL,值為-1,表示當前節(jié)點的后繼節(jié)點包含的線程需要運行,也就是unpark;
CONDITION,值為-2,表示當前節(jié)點在等待condition,也就是在condition隊列中;
PROPAGATE,值為-3,表示當前場景下后續(xù)的acquireShared能夠得以執(zhí)行;
值為0,表示當前節(jié)點在sync隊列中,等待著獲取鎖。
(6)AQS實現(xiàn)公平鎖和非公平鎖
非公平鎖中,那些嘗試獲取鎖且尚未進入等待隊列的線程會和等待隊列head結(jié)點的線程發(fā)生競爭。
公平鎖中,在獲取鎖時,增加了isFirst(current)判斷,當且僅當,等待隊列為空或當前線程是等待隊列的頭結(jié)點時,才可嘗試獲取鎖。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的Java 并发总结——AQS的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 并发总结——进程与线程
- 下一篇: 著名历史学家 你认识几个