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这个类里面完成的。
- allocateMemory putXX freeMemory pageSize
-