• atomic原子类的理解


    1.AtomicInteger等原子类的底层都是由Unsafe类的CAS思想和自旋锁实现。

    2.CAS思想是把自己的期望值和主存中的值进行比较,如果相同就赋值,不同就不赋值。CAS是CPU原语,是操作系统底层一系列指令实现,这些指令是连续的,所以是原子的。一般用到CAS的地方都有自旋,即先从主存中获取到值,然后执行CAS,如果主存中的值与刚获取的值相等,就赋要更新的值(下表中的update)。

    1、//这是AtomicInteger类的CAS
    public final boolean compareAndSet(int expect, int update) {//expect是期望值,用来与主存中的值进行比较,如果相同就把主存中的值改成update return unsafe.compareAndSwapInt(this, valueOffset, expect, update);//底层是调用unsafe类中的nativa方法 }
    2.//这个是AtomicInteger类中的获取并加1的方法
    public final int getAndIncrement() {
        //调用unsafe类中方法,valueOffset是这个对象在主存中的地址变量,也叫地址偏移量
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }
    /**
     *调用的unsafe类中源码
     *其实是先从主存中获值,然后再执行CAS,如果比较不相同,再从新获取值,执行CAS,一 
     * 直自旋
     */
    public final int getAndAddInt(Object var1, long var2, int var4) {
       int var5;
       do {//利用do-while自旋
           var5 = this.getIntVolatile(var1, var2);//从主存中获取值
       } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));//执行CAS
    
       return var5;
    }
    

    3.CAS与Sychronized的比较

      Synchronized是对一个对象加锁,锁的是整个对象,数据一致性可以保证,但并发性降低;

      而CAS没有用锁,是使用自旋的方式,先从内存中取值,然后再比较赋值,并发性和数据一致性都有了保证

    4.CAS的缺点:

      ①CAS使用的是自旋,CPU消耗大

      ②CAS引来了ABA问题:即t1和t2两个线程都在执行修改主存中的值A(都现将A拷到了本线程的工作内存中),某一时刻t2线程先将A改成了B(此时主存中变成了B),然后又将B改成了A(主存中又变成了A),然后t1线程执行CAS,compareAndSwap(A,C),一比较,认为主存中的值和期望值相同,所以就将主存中的值改成了C,此时t1线程却不知主存中的值经历了A-B-A的过程。这种问题的解决办法是:使用原子包中的AtomicStampedReference时间戳(又叫版本号)原子引用可以解决,即为主存中的值设置一个版本号,每次CAS时不仅比较值,还要比较版本号,都相同再赋值

    ——每天一小步,进步一大步,坚持。。。

     

     

  • 相关阅读:
    河南省第十二届大学生程序设计竞赛 F: Information Transmission-1(二分图最大匹配)
    hdu1068:Girls and Boys(最大独立集)
    hdu1068:Girls and Boys(最大独立集)
    hdu1281:棋盘游戏(二分图最大匹配)
    hdu1281:棋盘游戏(二分图最大匹配)
    洛谷P1991 :无线通讯网(最小生成树)
    洛谷P1991 :无线通讯网(最小生成树)
    oGitHub 注册
    Lambda应用设计模式 [转载]
    读取excel数据 到 datagrid 出现 找不到可安装的ISAM
  • 原文地址:https://www.cnblogs.com/yayin/p/14160436.html
Copyright © 2020-2023  润新知