保证了共享变量的可见性。所谓可见性指的是,某个线程对变量进行操作后,其他线程能够读取到操作后的最新结果。

    CPU通常不会直接与内存通信,内存中的数据首先会被读取到缓存中进行读写。当对声明了volatile的变量进行写操作时,JVM会向处理器发送一条Lock前缀的指令,表示将变量锁在的缓存行数据写回内存中。

    然而volatile并不能保证线程安全。

    volatile变量具有的特性如下

    可见性:总是能够读到任意线程对volatile变量最新的修改

    原子性:volatile无法实现原子性

    禁止指令重排序优化

具体的实现原理

  • 对volatile变量执行写操作时,会在写操作后加入一条store屏障指令

             对volatile变量执行写操作时,又会强制的将工作内存中的刚刚改变的值写到主内存中去

  • 对volatile变量执行读操作时,会在读操作前加入一条load屏障指令

            对volatile变量执行读操作时,都要强制的先从主内存读取最新的变量值到工作内存,然后再读工作内存中所存储的变量副本

 

使用场景

  • 运算结果并不依赖当前值,例如Boolean就可,而number++这样的就不行,这样的情况使用锁
  • 运算结果依赖当前值但是能够确保只有单一线程修改变量的值,例如ConcurrentHashMap中Segment的count变量:count变量只能由单一线程来改变(因为put和remove都是加锁的),但是修改后未必能及时刷新到主内存;这时候读线程去读取的话就可能读到旧数据。所以需要volatile来保证可见性。
  • 变量不需要与其他的状态变量共同参与不变约束,例如low<up这样的场景就不行
  • 在访问变量时需要使用锁,就不要使用volatile

      volatile只能实现部分线程安全(实际上只能实现可见性)。 如果volatile用得好的话,比synchronized强不少,因为不需要上下文切换。