CAS,AQS,volatile,native,synchronized,lock关键字解读以及它们之间的联系(高频面试)

1.CAS

CAS比较并交换,没啥好说的,下面来说一下具体实现底层

  •         CAS底层是由native修饰的,native是调用的本地C++代码Safe.app类中的  lock _IF_MP方法,什么意思呢?就是说如果(IF)计算机是多核状态下(MP)加锁(lock),在什么时候加锁呢,在比较并交换的时候
  •         相比于synchronized,CAS是基于cpu实现的数据一致性,而synchronized是基于jvm层操作的,锁的粒度可以更大。CAS的性能将会更高
  • Doug Lea在CAS的基础上帮助我们实现了一些原子类,其中就包括现在看到的AtomicInteger,还有其他很多原子类……

    CAS的缺点:CAS只能保证对一个变量的操作是原子性的,无法实现对多行代码实现原子性。

  • CAS的问题

  • ABA问题:问题如下,可以引入版本号的方式,来解决ABA的问题。Java中提供了一个类在CAS时,针对各个版本追加版本号的操作。 AtomicStampeReference

  • AtomicStampedReference在CAS时,不但会判断原值,还会比较版本信息。

  • public static void main(String[] args) {
        AtomicStampedReference<String> reference = new AtomicStampedReference<>("AAA",1);
    
        String oldValue = reference.getReference();
        int oldVersion = reference.getStamp();
    
        boolean b = reference.compareAndSet(oldValue, "B", oldVersion, oldVersion + 1);
        System.out.println("修改1版本的:" + b);
    
        boolean c = reference.compareAndSet("B", "C", 1, 1 + 1);
        System.out.println("修改2版本的:" + c);
    }
  • 自旋时间过长问题

    • 可以指定CAS一共循环多少次,如果超过这个次数,直接失败/或者挂起线程。(自旋锁、自适应自旋锁)
    • 可以在CAS一次失败后,将这个操作暂存起来,后面需要获取结果时,将暂存的操作全部执行,再返回最后的结果。

 2.AQS

        AQS的数据结构是一个volatile的state和一个双向队列,ReentrantLock底层是基于AQS实现的,有一个基于CAS维护的state变量来实现锁的操作,而ReentrantLock是Lock接口的一个实现

  3.Volatile

  •        Volatile 是怎么保证线程之间的可见性的呢?首先我们先了解一下X86硬件的内存屏障?

sfence: store| 在sfence指令前的写操作当必须在sfence指令后的写操作前完成。 lfence:load | 在lfence指令前的读操作当必须在lfence指令后的读操作前完成。 mfence:modify/mix | 在mfence指令前的读写操作当必须在mfence指令后的读写操作前完成。

原子指令,如x86上的”lock …” 指令是一个Full Barrier,执行时会锁住内存子系统来确保执行顺序,甚至跨多个CPU。Software Locks通常使用了内存屏障或原子指令来实现变量可见性和保持程序顺序

  •         接下来我们说一下volatile的实现细节

              

  1. 字节码层面 ACC_VOLATILE

  2. JVM层面 volatile内存区的读写 都加屏障

    StoreStoreBarrier

    volatile 写操作

    StoreLoadBarrier

    LoadLoadBarrier

    volatile 读操作

    LoadStoreBarrier

  3. OS和硬件层面 volatile与lock前缀指令_volatile class lock指令前缀_zhifeng687的博客-CSDN博客 hsdis -VoHotSpot Dis Assembler windows lock 指令实现 | MESI实现

        下面简单说一下MESI协议(硬件层数据一致性):

                缓存一致性协议:现代CPU的数据一致性实现 = 缓存锁(MESI ...) + 总线锁(据说是拉高北桥芯片上的一根电容,把通往资源的通道堵死,达到资源独占的目的)

        读取缓存以cache line为基本单位,目前64bytes

        位于同一缓存行的两个不同数据,被两个不同CPU锁定,产生互相影响的伪共享问题

        可以使用缓存行的对齐能够提高效率(定义7个Long 类型数据作为缓存行对齐)

经典面试题之(单列模式DDL双重检测为什么要加Volatile)?

        

        

半初始化:初始化时成员变量赋默认值,此刻INSTANCE=new T();instance已经不为空了

astore_1,指令重排乱序,先执行了m=0默认值,然后赋值给Instance(astore_1这个操作),然后才赋的初始值m=8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值