併發程式設計之AQS和鎖
一、AQS
1、AQS(AbstractQueuedSynchronizer抽象類):是一個用於構建鎖和同步容器的框架(通過繼承AQS並實現它的抽象方法),它不是通過synchronized給物件加鎖實現的,而僅僅只是一個工具類。
JUC包內許多類都是基於AQS構建,例如ReentrantLock,Semaphore,CountDownLatch,ReentrantReadWriteLock,FutureTask等。
2、實現
AQS內部實現主要是狀態變數state(volatile型別)和一個FIFO佇列來完成,同步佇列的頭結點是當前獲取到同步狀態的結點,獲取同步狀態state失敗的執行緒,會被構造成一個結點(或共享式或獨佔式)加入到同步佇列尾部(採用自旋CAS來保證此操作的執行緒安全
state:ReentrantLocky用它表示執行緒重入鎖的次數,Semaphore用它表示剩餘的許可數量,FutureTask用它表示任務的狀態。 對state變數值的更新都採用CAS操作保證更新操作的原子性。
3、AQS功能
1、獨佔鎖:ReentrantLock
2、共享鎖:CountDownLatch等
4、如何自己實現
1、繼承AbstractQueuedSynchronizer這個類;
2、然後根據需求去重寫相應的方法,要實現一個獨佔鎖,那就去重寫tryAcquire,tryRelease,要實現共享鎖,就去重寫tryAcquireShared,tryReleaseShared;
3、在我們的元件中呼叫AQS中的模板方法就可以了,而這些模板方法是會呼叫到我們之前重寫的那些方法的;
5、設計思想
AQS實現是經典的模板方法模式:只需要很小的工作量(重寫方法)就可以實現自己的同步元件,AQS為我們定義好頂級邏輯的骨架,並提取出公用的執行緒入佇列/出佇列,阻塞/喚醒等一系列複雜邏輯的實現,將部分簡單的可由使用者決定的操作邏輯延遲到子類中去實現即可。
二、鎖
synchronized:可以保證原子性、可見性和有序性;
CAS(Compare And Swap):原子操作,可以保證原子性
volatile:可以保證可見性、有序性
阻塞佇列BlockingQueue和併發容器ConcurrentMap中的很多同步都是通過ReentrantLock實現的。但ConcurrentHashMap在jdk1.8中換成了CAS+synchronized。AQS是API級別的後續優化空間很小,Synchronized是JVM直接支援的,有鎖粗化、鎖消除、鎖自旋特性,可以直接隨JDK版本升級而提升。
Ref:
https://www.cnblogs.com/chengxiao/archive/2017/07/24/7141160.html