天天看點

使用CAS、FAA實作無鎖程式設計(下)FAA用鎖、CAS和FAA完整實作賬戶服務

FAA

func transferFaa(balance *int32, amount int, done chan bool) {
    atomic.AddInt32(balance, int32(amount))
    done <- true
}      

java.util.concurrent.

atom

ic.AtomicLong#getAndAdd

  • FAA原語

    擷取變量目前值,然後把它做個加法,且保證該操作的原子性,一行代碼即可。你開始好奇了,那CAS還有何意義?

該案例肯定FAA更合适,但CAS适用範圍更廣。

類似邏輯:先讀資料,做計算,然後更新資料,無論這個計算啥樣,都可用CAS保護資料安全。

但FAA邏輯局限于簡單加減法。是以并非說CAS沒有意義。

使用CAS反複重試指派比較耗費CPU,因為for循環如果指派不成,會立即進入下一次循環,沒有等待的。如果線程間碰撞頻繁,經常反複重試,這重試的線程會占用大量CPU時間,系統性能就會下降。

緩解這問題的一個方法是使用Yield(), 大部分程式設計語言都支援Yield()系統調用。

Yield()作用

告訴os,讓出目前線程占用的CPU給其他線程。每次循環結束前調用下Yield(),可在一定程度上降低CPU使用率,緩解該問題。也可在每次循環結束後,Sleep()小段時間,但這樣性能會嚴重下降。

是以,這種方法它隻适于線程碰撞不太頻繁,即執行CAS不需要重試這樣的場景。

用鎖、CAS和FAA完整實作賬戶服務

ttps://github.com/shenyachen/JKSJ/blob/master/study/src/main/java/com/jksj/study/casAndFaa/CASThread.java

https://github.com/xqq1994/algorithm/blob/master/src/main/java/com/test/concurrency/MutxLock.java https://github.com/xqq1994/algorithm/blob/master/src/main/java/com/test/concurrency/CAS.java

參考

https://time.geekbang.org/column/article/130743
使用CAS、FAA實作無鎖程式設計(下)FAA用鎖、CAS和FAA完整實作賬戶服務