一旦一个变量被volatile修饰,就有两个含义:
1、保证线程之间的可见性
用volatile修饰共享变量,能够防止编译器等优化发生,让一个线程对共享变量的修改对另一个线程可见。
问题原因:程序运行时,jvm的JIT(即时编译器)会对执行次数多的代码进行优化,将其改为固定的值。即使改了变量,但是并不会再去读取变量的值。
解决方案:
a、在程序运行时加入vm参数-Xint,表示禁用即时编译器(不推荐,其他程序也许会使用)
b、在要读取变量的前面加上volatile修饰,告诉JIT不要对volatile修饰的变量进行优化。
实现原理:
写屏障会将写屏障之前的修改全部同步到主存当中
读屏障会将读屏障之后操作都去读主存中的内容不会去读缓存中的
2、静止进行指令重排
用volatile修饰共享变量会在读、写共享变量时加入不同的屏障,阻止其他读写操作越过屏障,从而达到阻止重排序的效果
解决方案:用volatile修饰,他是在共享变量加上不同的屏障保证不会进行指令重排序
volatile使用技巧:
写变量让volatile修饰的变量的在代码最后位置
读变量让volatile修饰的变量的在代码最开始位置