设计模式之单例模式

一、饿汉模式

 //饥饿模式
public final class EagerSingleton  {
    private static EagerSingleton singObj = new EagerSingleton();  

    private EagerSingleton() {
    }

    public static EagerSingleton getSingleInstance() {
        return singObj;
    }
}

性能问题:每个对象在没有使用之前就已经初始化了,如果这个对象很大呢?没有使用这个对象之前,就把它加载到了内存中去是一种巨大的浪费

二、懒汉模式

1、写法一

//懒汉模式
public final class LazySingleton {  
    private static LazySingleton singObj = null;  
  
    private LazySingleton() {  
    }  
  
    public static LazySingleton getSingleInstance() {
        if (null == singObj ) {
              singObj = new LazySingleton();
         }
        return singObj;
    }  
}

性能问题:线程不安全,多个线程可能同时运行判断singObj为null,于是同时进行了初始化

2、写法二

//懒汉模式加Synchronized 
public final class ThreadSafeSingleton {  
    private static ThreadSafeSingleton singObj = null;  
  
    private ThreadSafeSingleton() {  
    }  
  
    public static Synchronized ThreadSafeSingleton getSingleInstance() {  
        if(null == singObj ) {
            singObj = new ThreadSafeSingleton();
        }
        return singObj;
    }  
}

性能问题:同步的代价必然会一定程度的使程序的并发度降低

3、写法三

//双重检查锁
public final class DoubleCheckedSingleton {  
    private static DoubleCheckedSingletonsingObj = null;  
  
    private DoubleCheckedSingleton() {  
    }  
  
    public static DoubleCheckedSingleton getSingleInstance() {  
        if (null == singObj ) {
              Synchronized(DoubleCheckedSingleton.class) {
                     if(null == singObj) {
                           singObj = new DoubleCheckedSingleton();
                     }
              }
         }
       return singObj;
    }  
}

优点:这种写法使得只有在加载新的对象进行同步,在加载完了之后,其他线程就可以判断跳过锁的的代价,做到很好的并发度

4、写法四

//Initialization on Demand Holder
public class Singleton {    
    private static class SingletonHolder {    
        public final static Singleton instance = new Singleton();    
    }    
   
    public static Singleton getInstance() {    
        return SingletonHolder.instance;    
    }    
}

优点: 这种方法使用内部类来做到延迟加载对象,在初始化这个内部类的时候,JLS(Java Language Sepcification)会保证这个类的线程安全。这种写法最大的美在于,完全使用了Java虚拟机的机制进行同步保证,没有一个同步的关键字

三、防止序列化破坏单例模式

//添加这个hook函数,那么系统在反序列化的过程中就会通过该Hook方法得到原有的单例,而不是重新创建一个单例。
private Object readResolve() throws ObjectStreamException {
    return singleton;
}

发表评论