《head first》设计模式 day five 单例模式

单例模式的定义:确保一个类只有一个实例,并且提供一个全局访问点;书上说单例模式基本上是最简单的设计模式了,主要是面对重资产保持唯一性的主要设计原则。比如线程池,比如注册表,这些都要保持唯一性,否则系统资源紊乱,或者是环境配置不正确等问题。

单例模式:1饿汉模式;懒汉模式。2双重检查加锁模式

单例的进化:初始模式

class Singleton{
 private static Singleton instance= new Singleton();
 private Singleton(){}
 public static Singleton getInstance(){
    return instance;
}
}
这个单例在初始化的时候就已经实例化一个对象,属于饿汉模式,这个地方有很多隐藏的问题,比如我们这个的工程中有多个这样的单例,会因为jvm的加载顺序造成一些空指针问题,而且如果Singleton占用很多资源,在启动的时候加载会浪费很多的时间。

懒汉模式初始版:只有在我们需要的时候才会初始化这个实例。

class Singleton{
 private Singleton instance;
 private Singleton(){}
 public static Singleton getInstance(){
   if(instance==null){
      instance=new Singleton();
   }
   return instance;
 }
}
但是上面的例子在遇到多线程的时候就有可能会被初始化两次,

懒汉模式plus版

class Singleton{
 private Singleton instance;
 private Singleton(){}
 public Synchronized static Singleton getInstance(){
     if(instance==null){
         instance =new Singleton();
     }
    return instance;
 }
}
这样我们就可以控制并发,实现只实例化一次的效果,但是,这个地方会严重的影响我们的性能,毕竟我们只想控制实例化的次数,而不是控制每次的并发访问。

懒汉模式 plus plus版

class Singleton {
 private Singleton instance;
 private Singleton(){}
 public static Singleton(){
    if(instance==null){
        synchronized(Singleton.class){
             if(instance==null){
                   instance==new Singleton();
             }
        }
    }
}
}
上面就是我们最终的双重检测枷锁机制。

其实在我们后来的版本中,又有一种简单高效的饿汉模式,那就是枚举类单例,我们知道枚举类的设计原理就是在jvm中有且只能有一个实例,跟我们单例模式很像

枚举单例:

public enum SingleEnumTest {
	Singleton;
	private static JobTest instance = new JobTest();

	public static JobTest getInstance() {
		return instance;
	}
}
上面就是目前为止我们能用到的单例模式。不管怎么样,单例模式不宜多用,如果在程序中多次用到,那就要仔细思考是不是设计思想除了问题,是否可以用final static常量代替。

猜你喜欢

转载自blog.csdn.net/David_lou/article/details/79261720