zoukankan      html  css  js  c++  java
  • CAS自旋volatile变量

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

      

    我们先来看一下AtomicInteger类的getAndIncrement的源代码:
     

    这段代码写的很巧妙:
             1,compareAndSet方法首先判断当前值是否等于current;
             2,如果当前值 = current ,说明AtomicInteger的值没有被其他线程修改;
             3,如果当前值 != current,说明AtomicInteger的值被其他线程修改了,这时会再次进入循环重新比较;
       
        在getAndIncrement方法中,它的做法是:先获取到当前的 value 属性值,然后将 value 加 1,赋值给一个局部的 next 变量,然而,这两步都是非线程安全的,但是内部有一个死循环,不断去做compareAndSet操作,直到成功为止,也就是修改的根本在compareAndSet方法里面。
    我们可以看到在compareAndSet()方法中调用的是sun.misc.Unsafe.compareAndSwapInt(Object obj, long valueOffset, int expect, int update)方法,
    compareAndSwapInt 基于的是CPU 的 CAS指令来实现的。所以基于 CAS 的操作可认为是无阻塞的,一个线程的失败或挂起不会引起其它线程也失败或挂起。并且由于 CAS 操作是 CPU 原语,所以性能比较好。

    综上,getAndIncrement() 方法并不是原子操作。 只是保证了他和其他函数对 value 值得更新都是有效的。

    他所利用的是基于冲突检测的乐观并发策略。 可以想象,这种乐观在线程数目非常多的情况下,失败的概率会指数型增加。

  • 相关阅读:
    dedecms自定义表单提交获取时间跟ip地址
    JQuery购物车多物品数量的加减+总价计算
    jquery手机触屏滑动拼音字母城市选择器代码
    js实现图片上传实时显示
    js实现发送验证码倒计时效果
    JS 仿支付宝input文本输入框放大组件
    js实现倒计时效果
    jquery统计输入文字的个数并对其进行判断
    【Linux】Linux系统安全设置
    java泛型(generics)
  • 原文地址:https://www.cnblogs.com/shoshana-kong/p/10835744.html
Copyright © 2011-2022 走看看