最近作新項目,貨幣充值消耗,送禮競爭勳章等都使用了CAS解決併發問題,因此作一下筆記,談談CAS,你們一塊兒互相學習。算法
討論CAS的話,先來講有一下樂觀鎖,悲觀鎖。數據庫
悲觀鎖:每次去取數據,很悲觀,都以爲會被別人修改,因此在拿數據的時候都會上鎖。簡言之,共享資源每次都只給一個線程使用,其餘線程阻塞,等第一個線程用完後再把資源轉讓給其餘線程。synchronized和ReentranLock等都是悲觀鎖思想的體現。併發
樂觀鎖:每次去取數據,都很樂觀,以爲不會被被人修改。所以每次都不上鎖,可是在更新的時候,就會看別人有沒有在這期間去更新這個數據,若是有更新就從新獲取,再進行判斷,一直循環,直到拿到沒有被修改過的數據。CAS(Compare and Swap 比較並交換)就是樂觀鎖的一種實現方式。工具
1.須要讀寫的內存地址V學習
2.進行比較的預期原值A線程
3.擬寫入的新值Bcdn
若是內存位置的值V與預期原A值相匹配,那麼處理器會自動將該位置值更新爲新值B。CAS思想:要進行更新時,認爲位置V上的值仍是跟A值相等,若是是是相等,就認爲它沒有被別的線程更改過,便可更新爲B值。不然,認爲它已經被別的線程修改過,不更新爲B的值,返回當前位置V最新的值。blog
反編譯Unsafe類(用Java Decompiler工具) 內存
假設多人A,B,C等給D送禮,送總價值最多的那我的,能夠成爲佩帶D的守護皇冠,D的守護皇冠有且只有一個。若是他們同時在給D送禮,送禮價值互相超越,即存在併發問題。資源
解決思路: 參考樂觀鎖原理
搶佔守護流程圖:
代碼實現:
併發環境下,假設初始條件是A,去修改數據時,發現是A就會執行修改。可是看到的雖然是A,中間可能發生了A變B,B又變回A的狀況。此時A已經非彼A,數據即便成功修改,也可能有問題。
自旋CAS,若是一直循環執行,一直不成功,會給CPU帶來很是大的執行開銷。因此上面搶佔守護的例子,設置了嘗試的執行次數n,避免一直循環