老师在本节中10:55秒处的解释,说假如没有volatile修饰,线程2如果看不到线程1运行这句:instance = new Singleton6();,线程2就会走入if语句:
if(instance == null) {
instance = new Singleton6();
}
但是其实线程2是可以看到线程1运行这句的:instance = new Singleton6();,理由如下:
synchronized可以保证happens-before。当线程1在synchronized代码块中,线程2是被卡在synchronized代码块之外的,只有当线程1运行完synchronized代码块并释放monitor,线程2才能进入synchronized代码块,而当线程2进入到synchronized代码块中的时候,线程1之前在synchronized代码块中的所有修改已经对线程2可见了。
所以我认为这里的volatile关键字并不是为了保证可见性。只是单纯的为了禁止重排序。
不知道这样分析对不对,希望老师指教,谢谢!
参考资料:
// 双重检查的方法实现Singleton
public class Singleton6 {
private volatile static Singleton6;
private Singleton6(){ }
public static Singleton6 getInstance() {
if(instance == null) {
synchronized (Singleton6.class) {
if(instance == null) {
instance = new Singleton6();
}
}
}
return instance;
}
}