为什么AtomicInteger 还有compareAndSet()?
在ribbon的轮询负载均衡就是用了AtomicInteger的compareAndSet()来实现无锁
class SimulatedCAS{volatile int count;// 实现count+=1addOne(){do {newValue = count+1; //①}while(count !=cas(count,newValue) //②}// 模拟实现CAS,仅用来帮助理解synchronized int cas(int expect, int newValue){// 读目前count的值int curValue = count;// 比较目前count值是否==期望值if(curValue == expect){// 如果是,则更新count的值count= newValue;}// 返回写入前的值return curValue;}}
CAS 缺点
1、ABA问题。CAS比较交换时,是检查当前值与期望值是否一致。试想一下,如果某个值由A变成了B,再由B变回了A,那么在做CAS比较时,会认为值没有变化,但实际是发生了变化。ABA问题的解决思路是给数据加一个版本号,每次更新后对其版本加1,这样在值变回A之后,其版本已不是原来的版本了
2、开销大。在高并发情况下,自旋CAS如果长时间不成功,会一直执行循环操作,给CPU带来非常大的执行开销。所以其适用于那些并发不是很大的场景。
课后思考
cas的获取值 要放在循环体内
