FAA
func transferFaa(balance *int32, amount int, done chan bool) {
atomic.AddInt32(balance, int32(amount))
done <- true
}
java.util.concurrent.
atomic.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![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yY4IWOwImNhNDN5IjM0MmYzQzY0UzY3EmYhJmY0MGM48CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)