一、JUC包中的 CountDownLatch、CyclicBarrier、ReentrantLock和Semaphore都是基於AQS(AbstractQuenedSynchronizer)實現的node
在ReentrantLoc這個組件裏,stste表示獲取鎖的線程數,假如state=0,表示尚未線程獲取鎖,1表示有線程獲取了鎖。大於1表示重入鎖的數量。api
繼承:子類經過繼承並經過實現它的方法管理其狀態(acquire和release方法操縱狀態)。數據結構
能夠同時實現排它鎖和共享鎖模式(獨佔、共享),站在一個使用者的角度,AQS的功能主要分爲兩類:獨佔和共享。它的全部子類中,要麼實現並使用了它的獨佔功能的api,要麼使用了共享鎖的功能,而不會同時使用兩套api,即使是最有名的子類ReentrantReadWriteLock也是經過兩個內部類讀鎖和寫鎖分別實現了兩套api來實現的ui
二、AQS底層實現了一個FIFO的隊列。底層的數據結構是一個雙向鏈表;spa
三、AQS核心思想線程
若是被請求的共享資源空閒,則將當前請求資源的線程設置爲有效的工做線程,而且將共享資源設置爲鎖定狀態。若是被請求的共享資源被佔用,那麼就須要一套線程阻塞等待以及被喚醒時鎖分配的機制,這個機制AQS是用CLH隊列鎖實現的,即將暫時獲取不到鎖的線程加入到隊列中。code
四、CLH隊列(FIFO)對象
CLH隊列是一個虛擬隊列,沒有隊列實例只有節點與節點之間的關係。blog
AQS使用一個int成員變量來表示同步狀態,經過內置的FIFO隊列來完成獲取資源線程的排隊工做。AQS使用CAS對該同步狀態進行原子操做實現對其值的修改。繼承
當一個線程嘗試獲取鎖失敗後,就會把失敗信息封裝成一個node節點嘗試加入這個同步隊列。由於可能有多個線程都想加入隊列尾部,因此加入隊列是採用了cas + volatile。
加入隊列後獲取鎖的操做:隊列裏面的節點會觀察pre節點即前置節點的狀態,若是是否是頭結點就會阻塞,若是前面一個節點是頭結點就會被喚醒一直循環嘗試獲取鎖。
五、VarHandle
varHandle是jdk9以後加入的,handle的意思是句柄,VARHandle指的就是引用變量指向具體對象的那個引用
varHandle能夠直接給變量賦值,而且作一些原子操做
public class Demo { int x = 10; private static VarHandle varHandle; static { try { varHandle = MethodHandles.lookup().findVarHandle(Demo.class, "x", int.class); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static void main(String[] args) { Demo demo = new Demo(); //獲取變量值 System.out.println((int)varHandle.get(demo)); //爲變量賦值 varHandle.set(demo, 1); System.out.println(demo.x); //進行原子操做 varHandle.getAndAdd(demo,3); System.out.println(demo.x); } }