1、保证线程可见性
保证线程可见性就是将线程设置及时沟通,两个线程共享值的话,可能会出现一个线程将这个值修改后,另外一个线程还没读到这个修改后的值,出现不一致情况。如果加上volatile,相当于其中一个将这个值修改后,另一个线程立马收到修改够的值。
2、禁止指令重排序
单例模式的双重检查(程序表面上看是没啥问题的)要不要加上volatile,答案是要加上的。因为new一个对象要分为三步,第一是给对象开辟一段内存(变量默认初始值)、第二是给这个对象中成员变量赋值,第三是将这个值指向这个对象。这个时候如果有指令重排序就会发生可能拿到变量的默认初始值,会出现获得值不是想要的值。因为加上volatile会禁止指令重排序,所以很必要加上volatile。
下面是单例模式双重检查实现
public class Singleton {
private static volatile Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}