设计模式之单例模式

一、饿汉模式

01
02
03
04
05
06
07
08
09
10
11
//饥饿模式
public final class EagerSingleton  {
    private static EagerSingleton singObj = new EagerSingleton(); 
 
    private EagerSingleton() {
    }
 
    public static EagerSingleton getSingleInstance() {
        return singObj;
    }
}

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

二、懒汉模式

1、写法一

01
02
03
04
05
06
07
08
09
10
11
12
13
14
//懒汉模式
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、写法二

01
02
03
04
05
06
07
08
09
10
11
12
13
14
//懒汉模式加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、写法三

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
//双重检查锁
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、写法四

01
02
03
04
05
06
07
08
09
10
//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虚拟机的机制进行同步保证,没有一个同步的关键字

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

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

发表评论

欢迎阅读『设计模式之单例模式|Java、设计模式|Nick Tan-梓潼Blog』