静态类内部加载
使用内部类的好处是,静态内部类不会在单例加载时就加载,而是在调用getInstance()方法时才进行加载,达到了类似懒汉模式的效果,而这种方法又是线程安全的。
public class SingletonDemo { private static class SingletonHolder{ private static SingletonDemo instance=new SingletonDemo();
} private SingletonDemo(){
System.out.println("Singleton has loaded");
} public static SingletonDemo getInstance(){ return SingletonHolder.instance;
}
}
double check volatile
private volatile Resource resource;
public Resource getResource() {
Resource tmp = this.resource;
if (tmp == null) {
synchronized(this){
tmp = this.resource
if (tmp == null) {
this.resource = tmp = new Resource();
}
}
}
return tmp;
}
new Resource()
可以分解为:
memory =allocate(); //1:分配对象的内存空间
ctorInstance(memory); //2:初始化对象
instance =memory; //3:设置instance指向刚分配的内存地址
如果被重排为
memory = allocate(); //1:分配对象的内存空间
instance = memory; //2:设置instance指向刚分配的内存地址
ctorInstance(memory); //3:初始化对象
就会出现线程A中执行这段赋值语句,在完成对象初始化之前就已经将其赋值给resource引用,恰好另一个线程进入方法判断instance引用不为null,然后就将其返回使用,导致出错。将resource设置为volatile
之后,可以保证对相关操作的顺序。