使用CAS、FAA实现无锁编程(下)

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


使用CAS、FAA实现无锁编程(下)

上一篇:Juc05_线程池概述、创建方式、七大参数、底层工作原理、拒绝策略(一)


下一篇:phpexcel导入,出现PHPExcel_RichText Object解决办法