Volatile


JMM 内存模型

java的内存模型实现总是从主存(即共享内存)读取变量。在当前的内存模型下,线程可以把变量保存本地内存中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另一个线程还在继续使用副本的值,造成数据不一致

volatile

作用

1.volatile保证了变量的可见性

当cpu写数据的时候,如果发现操作是共享变量,即其他cpu也存在该变量的副本,会发出信号通知其他的cup变量缓存设置无效,当其他cpu读取这个变量时候,发现自己的缓存无效,就会从内存中重新读取。

volatile会控制被修饰的变量再内存操作上主动把值刷新到驻内存,JMM会把该线程对应的CPU内存设置过期,从主内存读取最新的值。

2.防止指令重排序

  1. volatile写在前面后面分别插入内存屏障
  2. volatile读在后面插入两个内存屏障
  3. 保证特定操作的执行顺序
  4. 保证某些变量内存可见性

volatile内存屏障故障是在读写操作的前后各添加一个屏障,也就是4个位置,来保证重排序的时候不能把内存屏障后面的指令重排序到内存屏障之前的位置。

如何保证可见性与防止指令重排

  1. 加了volatile关键字的成员变量,对这个变量进行修改的时候,会直接将cpu高级缓存中的数据写到主内存,对这个变量的读取也会直接从主内存读取,从而保证了可见性
  2. 加了volatile关键字的成员变量,会插入内存屏障,内存屏障可以达到禁止重排序的效果

注意:volatile不能解决原子性问题,如果要解决需要使用synchronized或者lock。




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • 2379. Minimum Recolors to Get K Consecutive Black Blocks
  • 2471. Minimum Number of Operations to Sort a Binary Tree by Level
  • 1387. Sort Integers by The Power Value
  • 2090. K Radius Subarray Averages
  • 2545. Sort the Students by Their Kth Score