volatile和cas

volatile

  • 保证线程可见性

    • MESI(它的本质上是使用了cpu的一个叫做高速缓存一致性协议)
    • 缓存一致性原则

    java里面有堆内存,堆内存是所有线程里面共享的内存,除了共享的内存之外,每个线程都有自己的专属区域,都有自己的工作内存,如果说在共享内存里有一个值的话,当我们某一个线程都要去访问这个值的时候,会将这个值copy一份,copy到自己的工作空间里面,然后对这个值进行改变,首先是在自己的空间里面改变,改完之后马上写回去。

  • 禁止指令重排序

    • DCL单例

    • Double Check Lock

      指令重排序和CPU有关系,每次写都会被线程读到,加了volatile之后,CPU原来执行一条指令的时候它是一步一步的顺序执行的,但是现在的CPU为了提高效率,它会把指令并发的来执行,第一个指令执行到一半的时候第二个指令可能就已经开始执行了,这叫做流水线式的执行。

      锁优化其中有一个叫做把锁粒度变细,还有一个把锁粒度变速

      CAS

      cas号称无锁优化,或者叫自旋。

      cas会产生ABA问题

      cas(旧值,新值)

      某一些特别常见的操作,老是来回加锁,加锁的情况特别多,所以java就提供了这些常见的操作这么一个类,这些类的内部就自动带了锁,这些锁的实现并不是synchronized重量级锁,而是CAS的操作来实现的。

      ABA问题

      假如说你有一个值,我拿到这个值是1,想把它变成2,我拿到1用CAS操作,期望值是1,准备变成2,这个对象Object,在这个过程中,没有一个线程改过我肯定是可以改的,但是如果有一个线程先把这个变成2后来又变回1,中间值更改过,它不会影响我这个CAS操作,这就是ABA问题。

      如果是基础类型的:无所谓,不影响结果值

      如果是引用类型的:中间发生了改变

      Unsafe

      直接操作内存

      • allocateMemory putXX freeMemory pageSize
        直接生成类实例
      • allocatelnstance
        直接操作类或实例变量
        -objectFieldOffset
        -getInt
        -getObject
        CAS相关操作
        -weakCompareAndSetObject Int Long

      这个类里面的方法非常非常多,而且这个类除了用反射使用之外,其它不能使用,不能使用的直接原因,和ClassLoader是有关系的。所有的Atomic操作内部下面都是CompareAndSetl这样的操作,那个CompareAndSetl就是在Unsafe这个类里面完成的。

posted @ 2020-09-23 15:26  striver-sc  阅读(251)  评论(0编辑  收藏  举报