- 概念
- 轻量级的同步机制
- 特征
- 保证可见性
- 在某个线程改变变量时及时通知其他线程该变量已被修改
- 不保证原子性
- 非线程安全
- 解决方法
- 在并发包中提供了多种解决方法,如在进行number++时,可使用AtomicInteger实现增减操作
- 原理:CAS/自旋锁
- 使用sync
- 在并发包中提供了多种解决方法,如在进行number++时,可使用AtomicInteger实现增减操作
- 禁止指令重排
- 指令重排
- 单线程确保最终执行结果和程序顺序一致
- 处理器在进行重排时必须考虑指令的数据依赖性
- 多线程环境下由于编译器优化,指令执行顺序会变化,无法确定两个线程使用的变量的一致性
- volatile禁止指令重排的原理
- 内存屏障(内存栅栏)
- 保证特定操作的执行顺序
- 保证某些变量的内存可见性(利用该特性实现volatile内存可见性)
- 使用
- 通过插入内存屏障禁止在内存屏障前后的指令执行重排优化
- 强制刷出CPU缓存数据(及时通知)
- 内存屏障(内存栅栏)
- 案例
- 单例模式
-
DCL双端检索机制 存在指令重排的可能性
- 原因:正常情况是先初始化再有一个指针指向该内存空间,有可能在指令优化之后在指向内存空间时,实际对象的初始化还未完成
- 解决:
public class SingletonDemo { private static volatile SingletonDemo instance = null; private SingletonDemo() { System.out.println(Thread.currentThread().getName() + "构造方法"); } //DCL双端检索机制 存在指令重排的可能性 public static SingletonDemo getInstance() { if (instance == null) { synchronized (SingletonDemo.class) { if (instance == null) { instance = new SingletonDemo(); } } } return instance; } }
-
- 单例模式
- 指令重排
- 保证可见性