单例

2018-06-10  本文已影响0人  西华子

静态类内部加载
使用内部类的好处是,静态内部类不会在单例加载时就加载,而是在调用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之后,可以保证对相关操作的顺序。

上一篇 下一篇

猜你喜欢

热点阅读