- cas機制
- cas和synchronized 區別,場景,有缺點
- cas底層實現、ABA問題場景、解決辦法
場景:公共內存值v=10,線程a,b分別對10進行5次++操作,最后結果20。
問題如果不加鎖,a得到內存值10在進行++操作時,b也獲得內存值10進行++操作。
此時就會出現結果<20的情況。
一、
cas機制:compare and swap(比較和替換)
cas三個操作數:V(內存值) A(舊的預期值) B(新值)
cas的使用場景:juc下lock、atomic操作
cas樂觀鎖(循環內自旋),原理:A=獲得內存值,B=對A進行累加操作后的值。更新內存值V為B的時候先將V和A對比,
如果相等,那么V替換B退出循環,如果不相等,重新獲得內存值,進行操作。
此套流程如何保證內存值是最新的?詳見volatile原理
此套流程如何保證V,A比較B替換V時是原子操作?cas底層用unsafe直接訪問底層操作系統,做了硬件級別的原子操作。
二、
synchronized:悲觀鎖,當synchronized鎖住后,其它線程處於blocking狀態,當其余線程獲得鎖后,
會進入runnable狀態,這個過程中涉及到操作系統用戶模式和內核模式的轉換,代價比較高。
並發量很高的話,synchronized還是比較適合的。
三、
cas優點:如一描述在並發量不是很高時cas機制會提高效率。
cas缺點:
1、cpu開銷大,在高並發下,許多線程,更新一變量,多次更新不成功,循環反復,給cpu帶來大量壓力。
2、只是一個變量的原子性操作,不能保證代碼塊的原子性。
3、ABA問題
四、
aba問題:內存值V=100;
threadA 將100,改為50;
threadB 將100,改為50;
threadC 將50,改為100;
場景:小牛取款,由於機器不太好使,多點了幾次全款操作。后台threadA和threadB工作,
此時threadA操作成功(100->50),threadB阻塞。正好牛媽打款50元給小牛(50->100),
threadC執行成功,之后threadB運行了,又改為(100->50)。
牛氣沖天,lz錢哪去了???
如何解決aba問題:
對內存中的值加個版本號,在比較的時候除了比較值還的比較版本號。
java:AtomicStampedReference就是用版本號實現cas機制。
