认识CAS自旋

概念

  比较并交换,简单来说,预期值与内存的值比较,相等则更新,否则循环下去

理解

  内存里存的一个值,你拿去,在更新的时候调用,如果这期间没人动过这个值,你可以更新,

否则,重复操作,直至成功。

  对一个值自增的自旋操作,伪代码如下:

  

public final int getAndIncrement() {
                 for (;;) {
                       int current = get();  // 取得内存里数值
                     int next = current + 1;  // 加1
                     if (compareAndSet(current, next))   // 调用compareAndSet执行原子更新操作
                         return current;
                 }
             }

结合例子

黑盒,存一个数字i,初始为0


线程A,B,C

线程A,

扫描二维码关注公众号,回复: 10090391 查看本文章

  第一次自旋:去黑盒拿一个数字,假设这时候为0,B和C拿到值为0,还未更新i值,A更新是(expect:0, update:1),执行成功,此时黑盒里i为1

线程B,
  第一次自旋:执行(expect:0, update:1),因为这时候被A更新为1了,所以失败,
  第二次自旋:再去拿值,这时候拿到的是1,假设这时候C还未更新,执行(expect:1,update:2),更新成功,此时黑盒里i为2
线程C,
  第一次自旋失败,原因如B
  第二次自旋:因为被B抢先了,所以也失败
  第三次自旋:拿到的值为2,执行(expect:2,update:3),成功

总结

  自旋的意思,多个线程夺取锁,那就必须先让自己得到的值跟内存的值一样才能操作

ABA问题

  线程A拿到的值是X,但X有可能被另一个线程B改为Y,又改为X,线程A这种情况下视为没有发生过变化,其实变化了,对此,AtomicStampedReference 

提供了依据版本号判断变化的实现。

猜你喜欢

转载自www.cnblogs.com/bloodthirsty/p/12552539.html
Cas
今日推荐