java 虚拟机提供的轻量级的同步机制(无锁)
- 保证可见性 (保证数据内存块的可见性,禁止加在引用类型上,有时候有效,有时候无效)
----- 缓存一致性协议(MESI)
----- hotspot 实现 (lock addl 锁总线)- 不保证原子性
- 禁止指令重排 (保证有序性)
使用内存屏障保证有序性
内存屏障: 屏障两边的指令不可以重排! 保障有序!
- 代码中加 volatile
- 字节码表示为 ACC_VOLATILE
- JVM (JSR规范 要求所有虚拟机实现 LoadLoad,StoreStore,LoadStore,StoreLoad 屏障 前后都加)
StoreStore LoadLoad
volatile 读操作 volatile 写操作
StoreLoad (写之前全部读完) LoadStore (读之前全部写完)
DCL(Double Check Lock) 需要加 volatile
- new 对象 并不是原子操作,其步骤参考对象创建过程
- 如果cpu发生指令重排序,init 和 引用关联交换,其他线程有可能会拿到一个半初始化状态的对象
- 虽然volatile 不能完全保证对象的可见性 但是可能保证禁止指令重排序
private volatile Test t;
private int m;
private Test(){
m=8;
}
public static Object test(){
if(t == null){
synchronize(Test.class){
if(t == null){
t = new Test();
}
}
}
return t;
}