zoukankan      html  css  js  c++  java
  • 认识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,

      第一次自旋:去黑盒拿一个数字,假设这时候为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 

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

    每一步脚印都要扎得深一点!
  • 相关阅读:
    小学四则算式扩充
    软件工程初涉之感
    回头
    个人最终总结
    团队作业
    结对编程
    老李的blog使用日记(3)
    进度
    老李的blog使用日记(2)
    红果果
  • 原文地址:https://www.cnblogs.com/bloodthirsty/p/12552539.html
Copyright © 2011-2022 走看看