多线程与高并发(二)
volatile关键字
保证线程可见性
-
如果不加volatile关键字 线程A更改的数据 线程B获取新数据的时间不可控制 线程间不可见
即堆内存中的数据是否变化 和 线程B是否读取到堆内存中的数据 不可控制
-
加了volatile之后线程间数据可见性
MESI CPU的缓存一致性协议
禁止指令重排序
-
编译器编译期间可能会发生指令重排(目的是为了更快的让CPU执行)
-
DCL单例
-
Double Check Lock
-
Mgr06.java
-
loadfence原语指令
-
storefence原语指令
单例模式中的双重检查加锁
-
INSTANCE 单例对象上是否需要添加volatile关键字?
需要 防止指令重排序
INSTANCE = new Mrg06()这行代码中 注意:JVM给对象初始化时
- 给对象申请内存
- 给对象的成员变量初始化
- 把内存的内容赋值给INSTANCE
超高并发情况下 可能会出现由于指令重排导致的对象数据不准确的情况
synchronized优化
锁的细化
- 锁定的代码越少越好
锁的粗化
- 锁的争用非常频繁时 考虑粗化锁
锁定的对象出现变化
-
即锁定的object被重新初始化之类的
利用final关键字修饰对象
CAS(无锁优化 自旋)
Atomic原子类
-
Compare And Set
-
cas(V, Expected, NewValue)
-
if V == E
V = New
otherwise try again or fail
-
-
CPU原语支持
-
ABA问题
- 添加版本号控制(cas中添加version的比较)
Unsafe类
- weakCompareAndSet(弱指针)