单例模式中volatile到底是指令重排还是线程间变量可见导致的啊,网上说是重拍,但我感觉第二个也行?
if (a == null) {
//线程A,B同时从进入这里,A先进去,运行结束,根据JMM内存模型,
//线程A从主内存中将共享变量读入线程A的工作内存后并进行操作,之后将数据重新写回到主内存中;
//线程B从主存中读取的共享变量
//如果不加volatile,则B有可能读到的是非最新数据,老数据null,导致“脏读”
//B线程则会又创建了个A对象,非单例
synchronized (a.class) {
if (a == null) {
a = new A();
}
}
}
禁止重排是保证线程间变量可见的前提
加上volatile无非就是要保证单例对象的初始化操作会在下一个判空前初始化结果可见。
这里不涉及线程间变量可见的问题
除非是静态变量
否则线程间变量本来就不可见啊
当然这里a是个静态变量
但是跟可见性也没有什么关系
就是因为没有加锁,会导致操作非原子性