---- 什么是CAS機制
CAS機制主要是發生於Java中原子操作類(JUC)的底層實現中,其中在CAS機制中包含3個基本參數:內存地址V、舊預期值A、要修改的新值B。
當要更新一個變量的時候,只有當變量的預期值A和內存地址V當中的實際值相同的時候,才會將內存地址V對應的值修改為B
舉個栗子
- 在一個內存地址為V內存中,儲存着變量值10(即此時A=10)
- 此時,來了一個線程A,想對該變量進行增加1操作(即此時對線程A來說:A=10,B=11)
- 但是,當線程A操作之前,被線程B插入率先將該變量進行修改成11(即此時A=11)
- 接着,等線程A想來修改的時候,通過內存地址V獲取當前最新的值與自身線程的預期值進行比對(此時線程A的A=10),發現不一樣,導致更新失敗
- 線程A重新獲取內存地址V的當前值,並重新計算想要修改的新值,即自旋操作。(此時對線程A來說,A=11,B=12)
- 這一次沒有其他線程的干擾,線程A通過獲取內存地址V的實際值,成功比較后,並且將內存地址V的值修改成12
--- 優點
由於Synchronized是個重量級別的鎖,每次使用會引起用戶態和核心態之間進行轉換,在轉換之間需要耗費很多的處理時間,所以,如果使用CAS機制,在並發不是很多的情況下,可以減少用戶態和核心態進行切換,從而提高系統性能。
---缺點
- cpu開銷大,在高並發下,許多線程,更新一變量,多次更新不成功,循環反復,給cpu帶來大量壓力
- 只是一個變量的原子性操作,不能保證代碼塊的原子性
- ABA問題(不過一般極少出現)
舉個栗子(ABA問題)
- 小埋去存銀行卡有200塊錢,去提款機取錢100,恰巧機器有點問題,在進行取款提交操作后台開啟了兩個線程A和B(200->100)
- 線程A成功執行,而且線程B阻塞了,此時小埋銀行卡的余額為100
- 此時,小埋的哥哥給她卡了打了100塊,此時小埋銀行卡的余額為200
- 然后,線程B此時就又開始執行了,發現卡里的余額200和自身線程余額期待值一樣,進行修改(200->100)
- 最后,小埋就只能去找櫃台尋求幫助了,因為正常情況下,她現在的卡里應該還有200塊
如何解決aba問題:
對內存中的值加個版本號,在比較的時候除了比較值還的比較版本號。
參考資料:
《深入了解Java虛擬機》
