1. 程式人生 > >併發程式設計之AQS和鎖

併發程式設計之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

https://blog.csdn.net/luofenghan/article/details/75065001