上周去面试,手写单例类
然后我手写一个平时用的比较多的全局设置类:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Setting {
private static Setting setting;
private static Lock lock = new ReentrantLock();
private Setting(){
}
public static Setting get() {
if(setting != null) {
return setting;
}
lock.lock();
if(setting == null) {
setting = new Setting();
}
lock.unlock();
return setting;
}
}
结果面试官非说这单例在JVM指令重排序的情况下会出问题,非说必须为setting对象加一个volatile,当时很懵逼,现在也很懵逼。本人小白,各位大神分析一下?
指令重排序是为了优化指令,提高程序运行效率。
比如instance = new Singleton() 可分解为:
在第三行代码不依赖第二行代码的情况下,JVM会发成重排序:
重排序之后的代码,在单线程情况下执行没什么影响,多线程的话执行顺序如下:
线程A:
线程B:
解决方法:
private static Setting setting;
改为private static volatile Setting setting;
volatile
是jdk1.5之后加入的特性,可以禁止变量使用重排序。码字不易,有用望采纳