JAVA 并發(fā)的核心CAS與AQS

JAVA在大型機(jī)時(shí)代就專注于多線程,火到線程也完全得益于原生多線程的強(qiáng)大。多線程必然帶來(lái)一個(gè)問(wèn)題,資源的同步問(wèn)題。java有很多同步手段,但是追根到底就是CAS與AQS

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CAS

CAS就是CompareAndSwap,翻譯過(guò)來(lái)就是:比較與替換,預(yù)期值與內(nèi)存值比較,true就更新新值,false就不進(jìn)行任何操作,這是個(gè)死循環(huán),比較的過(guò)程會(huì)一直執(zhí)行。舉個(gè)例子:


其中flag.compareAndSet(true,false)的返回值為true就是獲得到了鎖,并且把flag的值置為false,所以內(nèi)存中的值變?yōu)閒alse,下個(gè)搶購(gòu)線程來(lái)臨時(shí),整個(gè)在進(jìn)行flag.compareAndSet(true,false)時(shí),返回值就變?yōu)閒asle,返回?fù)屬?gòu)失敗。直到上一個(gè)線程把flag把值重新置為fasle,才能搶購(gòu)成功。

當(dāng)然,如果搶購(gòu)非常激烈的話,CAS(本質(zhì)上是樂(lè)觀鎖)性能不一定比Sync好,說(shuō)穿了就是占著線程不還,在死循環(huán),避免內(nèi)核態(tài)用戶態(tài)線程切換導(dǎo)致的性能損耗,但是如果競(jìng)爭(zhēng)太過(guò)激烈,死循環(huán)也拿不到執(zhí)行權(quán),會(huì)導(dǎo)致CPU性能的浪費(fèi)。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AQS

AQS就是AbstractQueuedSynchronizer,常見(jiàn)的ReentrantLock,Semaphare,CounDownLatch等等同步類,實(shí)現(xiàn)都靠他。

AQS實(shí)際就三個(gè)元素 ,被執(zhí)行的資源狀態(tài),當(dāng)前執(zhí)行者,后面排隊(duì)等著的執(zhí)行者。

被執(zhí)行資源狀態(tài):要不就是0,要不是1,要不比1大。0的時(shí)候代表沒(méi)線程執(zhí)行,1的時(shí)候說(shuō)明被執(zhí)行了,比1大代表被重入了(就是被當(dāng)前的執(zhí)行者反復(fù)來(lái)回的獲得執(zhí)行權(quán))。

當(dāng)前執(zhí)行者:就是取得被執(zhí)行資源的執(zhí)行權(quán),可重入,除非把資源釋放,后面等著的執(zhí)行者獲取不到執(zhí)行權(quán)(需要一直釋放到0)

后面的排隊(duì)等待著:一個(gè)雙向隊(duì)列,其中的節(jié)點(diǎn)在自旋等待執(zhí)行權(quán),抄襲一張圖(來(lái)自https://www.cnblogs.com/waterystone/p/4920797.html)。


這張圖基本是對(duì)的,最后的成為節(jié)點(diǎn)成隊(duì)頭有點(diǎn)問(wèn)題,實(shí)際一旦等待著獲得執(zhí)行權(quán)就會(huì)彈出雙向隊(duì)列,并不在等待隊(duì)列中。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容