Java的AQS基本原理詳細分析
AQS基本原理
AQS是Abstract Queued Synchronizer的簡稱。AQS提供了一種實現(xiàn)阻塞鎖和一系列依賴FIFO等待隊列的同步器的框架。
從使用層面來說,AQS的功能分為兩種:獨占和共享。
- 獨占鎖,每次只能有一個線程持有鎖,比如前面給大家演示的ReentrantLock就是以獨占方式實現(xiàn)的互斥鎖;
- 共享鎖,允許多個線程同時獲取鎖,并發(fā)訪問共享資源,比如ReentrantReadWriteLock。
AQS內(nèi)部有以下幾個重要的數(shù)據(jù)結(jié)構(gòu):
- state變量,記錄鎖定狀態(tài),默認0
- 加鎖線程變量,記錄當前持有鎖的是哪個線程,默認null
- 線程等待隊列
以ReentrantLock為例,加鎖代碼如下:
ReentrantLock lock = new ReentrantLock(); lock.lock(); //------業(yè)務(wù)邏輯------- ....... //-------------------------- lock.unlock();
例如線程1和線程2進行加鎖操作,線程1先獲得鎖,AQS會將state置為1,并且加鎖線程變量記錄為線程1。線程2由于沒有獲得鎖,會被AQS放到線程等待隊列中進行等待。
ReentrantLock翻譯成中文是可重入鎖,從名字就可知它和synchronized關(guān)鍵字一樣是可重入的。因為有一個加鎖線程變量當前記錄了持有鎖的是哪個線程,ReentrantLock再次加鎖時,是可以成功的,相應(yīng)的state變量也會加1。和synchronized關(guān)鍵字一樣,有一次加鎖操作就必須對應(yīng)一次解鎖操作,解鎖一次,state變量會減1。
當線程1執(zhí)行完成,所有鎖定操作都對應(yīng)執(zhí)行了解鎖操作后,state變量為0,并且加鎖線程變量被置為null。此時會喚醒線程等待隊列中的第一個線程(線程2)去嘗試獲得鎖了。
但是如果此時恰好有一個新的線程3搶在線程2之前獲得了鎖,那么線程2只能繼續(xù)等待,這很不公平呀!而ReentrantLock默認的就是不公平鎖。如果希望獲得的是公平鎖,新來的線程必須在線程等待隊列中排隊等待,也很簡單,只需要構(gòu)造ReentrantLock對象時,指定true的參數(shù)即可。
ReentrantLock lock = new ReentrantLock(true);
到此這篇關(guān)于Java的AQS基本原理詳細分析的文章就介紹到這了,更多相關(guān)AQS基本原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot隨機數(shù)設(shè)置及參數(shù)間引用的操作步驟
在Spring Boot配置文件中設(shè)置屬性時,除了可以像前面示例中顯示的配置屬性值外,還可以使用隨機值和參數(shù)間引用對屬性值進行設(shè)置。下面給大家介紹SpringBoot參數(shù)間引用隨機數(shù)設(shè)置的操作步驟,感興趣的朋友一起看看吧2021-06-06使用通過ARP類似P2P終結(jié)者實現(xiàn)數(shù)據(jù)封包
目前網(wǎng)絡(luò)上類似P2P終結(jié)者這類軟件,主要都是基于ARP欺騙實現(xiàn)的,網(wǎng)絡(luò)上到處都有關(guān)于ARP的介紹,不過為了本文讀者不需要再去查找,我就在這里大概講解一下2012-12-12SpringBoot中@MessageMapping注解的原理及使用詳解
這篇文章主要介紹了SpringBoot中@MessageMapping注解的原理及使用詳解,@MessageMapping注解是Spring Boot提供的一個重要的注解之一,它可以幫助我們處理WebSocket消息,需要的朋友可以參考下2023-07-07Mybatis配置之<properties>屬性配置元素解析
這篇文章主要介紹了Mybatis配置之<properties>屬性配置元素解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07