CAS機制(多線程)


---- 什么是CAS機制

   CAS機制主要是發生於Java中原子操作類(JUC)的底層實現中,其中在CAS機制中包含3個基本參數:內存地址V、舊預期值A、要修改的新值B

   當要更新一個變量的時候,只有當變量的預期值A和內存地址V當中的實際值相同的時候,才會將內存地址V對應的值修改為B

舉個栗子

  1.  在一個內存地址為V內存中,儲存着變量值10(即此時A=10)
  2. 此時,來了一個線程A,想對該變量進行增加1操作(即此時對線程A來說:A=10,B=11)
  3. 但是,當線程A操作之前,被線程B插入率先將該變量進行修改成11(即此時A=11)
  4. 接着,等線程A想來修改的時候,通過內存地址V獲取當前最新的值與自身線程的預期值進行比對(此時線程A的A=10),發現不一樣,導致更新失敗
  5. 線程A重新獲取內存地址V的當前值,並重新計算想要修改的新值,即自旋操作。(此時對線程A來說,A=11,B=12)
  6. 這一次沒有其他線程的干擾,線程A通過獲取內存地址V的實際值,成功比較后,並且將內存地址V的值修改成12

--- 優點

    由於Synchronized是個重量級別的鎖,每次使用會引起用戶態和核心態之間進行轉換,在轉換之間需要耗費很多的處理時間,所以,如果使用CAS機制,在並發不是很多的情況下,可以減少用戶態和核心態進行切換,從而提高系統性能。

---缺點

  • cpu開銷大,在高並發下,許多線程,更新一變量,多次更新不成功,循環反復,給cpu帶來大量壓力
  • 只是一個變量的原子性操作,不能保證代碼塊的原子性
  • ABA問題(不過一般極少出現)

舉個栗子(ABA問題)

  1. 小埋去存銀行卡有200塊錢,去提款機取錢100,恰巧機器有點問題,在進行取款提交操作后台開啟了兩個線程A和B(200->100)
  2. 線程A成功執行,而且線程B阻塞了,此時小埋銀行卡的余額為100
  3. 此時,小埋的哥哥給她卡了打了100塊,此時小埋銀行卡的余額為200
  4. 然后,線程B此時就又開始執行了,發現卡里的余額200和自身線程余額期待值一樣,進行修改(200->100)
  5. 最后,小埋就只能去找櫃台尋求幫助了,因為正常情況下,她現在的卡里應該還有200塊

如何解決aba問題:
對內存中的值加個版本號,在比較的時候除了比較值還的比較版本號。

 

參考資料:

  《深入了解Java虛擬機》

   漫畫:什么是 CAS 機制?

  漫畫:什么是CAS機制?(進階篇)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM