volatile

96 阅读1分钟

两点内存语义

1、保证多线程对 变量操作的内存可见性

通过 synchronized 和 Lock 也能够保证可见性,线程在释放锁之前,会把共享变量值都刷回主存,但是相比于 volatile,synchronized 和 Lock 的开销都更大。

2、禁止指令重排序

内存中的语义是通过内存屏障实现:

  • 第一个为读操作时,第二个任何操作不可重排序到第一个前面。
  • 第一个为写操作时,第二个的读写操作也不运行重排序。
  • 第二个为写操作时,第一个任何操作不可重排序到第二个后面。

volatile 的原子性

volatile是线程不安全的: volatile 的两点内存语义能保证可见性和有序性,但是不能保证原子性:对单个 volatile 变量的读/写具有原子性,但是对于类似 volatile++ 这样的复合操作就无能为力了,要想保证原子性,只能借助于 synchronized、Lock 或者并发包下的 atomic 的原子操作类了。

volatile使用场景

(1)状态量标记:这种对变量的读写操作,标记为 volatile 可以保证修改对线程立刻可见,效率也比 synchronized、Lock 有一定的提升。

(2)避免指令重排序

指令重排序会导致,当一条线程访问的 instance 不为 null 时,但是实际上 instance 实例未必已初始化完成,也就造成了线程安全问题。