二十三种设计模式之一单例模式

方式一:首先不考虑并发的情况下:

public class Singleton{
		private static  Singleton singleton  = null;                                                                     
		public Singleton getInstance(){                                                                                     
			if(null == singleton){                                                                                  
				 singleton = new Singleton();	                                                                  
			}                                                                                                                                    
		return singleton ;                                                                                                
	}
}

方式二:加锁(不考虑效率)

	public class Solution {
		private  static Solution singleton = null;
		public  synchronized  static Solution getInstance(){
			if(null == singleton){
				singleton = new  Solution();
				}			
			return singleton;
		}			
	}

方式三:(双重检查加锁DCL(Double-Check-Locked))

public class Solution {
	/**
	 * @return: The same instance of this class every time
	*/
	private static Solution singleton = null;
	    
	    public static Solution getInstance() {
	       if(singleton == null){
	           synchronized (Solution.class){
	               if(singleton == null){
	                   try{
	                        singleton = (Solution)Class.forName("Solution").newInstance();
	                   }catch(Exception e){
	                       e.printStackTrace();
	                   }
	               }
	           }
	       }
	        return singleton;
	    }
	};
								

它的工作原理是:首先检查是否在没有同步的情况下需要初始化,如果singleton引用不为空,则无需初始化,直接使用它即可。否则就进行同步并再次检查singleton是否被初始化,从而保证了只有一个线程对singleton执行初始化。但是:在第一次检查的时候,由于没有采用同步,有可能得到一个“仅被部分构造的对象”,从而得到一个不正确(尚未初始化完成)的对象。产生这种糟糕结果的原因那就是java内存模型的指令冲排序现象——jvm为了优化程序性能而对指令重新排序执行的现象。
优化方案则是

public class Singleton{
	private volatile static Singleton singleton;
	public  static Singleton getInstance(){
		if(null == singleton){
			synchronized(Singleton.class){
				if(null == singleton){
					singleton = new Singleton();
					}
			}
		}
	return singleton;
	}
}

不过该优化方案在java5.0及更高的版本中才能生效。DCL的这种方案已经被广泛的废弃掉了。更通用的做法是采用延迟化占位类模式
方式四:即非延迟性加载方式,在类创建的同时就实例化一个singleton静态对象,在第一次调用的时候,速度会比延迟化加载模式要快,因为已经初始化完成。

public class Solution{
	private static Solution singleton = new Solution();;
	public static  Solution getInstance(){
		return singleton;
	}
}

方式五:本质上同方式四没有多大区别

public class Solution{
	private static Solution singleton = null;
	static {
		singleton = new Solution();
	}
	public static Solution getInstance(){
		return singleton;
	}
}

方式六:静态内部类(延迟化占位类方式) JVM推迟Solution的初始化操作,当开始调用getInstance()的时候Solution才会初始化,从而达到懒加载的目的。

public class  TestClass{
	public static Solution getInstance(){
		return Solution.singleton;
	}
	 static class Solution{
		private static Solution singleton=new Solution();
	}

}

方式七:枚举类型实现单例模式
避免序列化和反序列化得到单例对象不相同,以及通过反射机制调用对象的私有构造方法来构造单例对象的弊端:

public enum  EnumSingleton {
    INSTANCE;
    public EnumSingleton getInstance(){
        return INSTANCE;
    }
}
发布了30 篇原创文章 · 获赞 27 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章