使用volatile修饰符修饰共享变量(类的成员变量或者类的静态成员变量)会产生两个效果:
1:保证了不同线程对这个变量操作的可见性,即:一个线程修改了这个变量的值,修改结果对其他线程是立即可见的;
2:禁止指令重排序;
使用volatile关键字,会强制性的将修改的值立即写入主存;当线程2进行修改时,会导致线程1的工作内存中缓存变量stop缓存
行无效(反映到硬件层的话,就是cpu的L1或者L2缓存中对应的缓存行无效);由于线程1的工作内存中缓存变量的缓存行无效,
所以线程1再次读取变量stop的值时,会去主存读取。
下面这段话摘自《深入理解Java虚拟机》:
“观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”
lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
2)它会强制将对缓存的修改操作立即写入主存;
3)如果是写操作,它会导致其他CPU中对应的缓存行无效。
volatile不等同于synchronized,synchronized防止多个线程同时访问同一段代码,影响执行效率;volatile关键字无法保证原子性;